<commit_before>﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using RazorEngine;

namespace RazorReport {
    public class ReportBuilder<T> : IReportBuilder<T> {
        string name;
        string template;
        string masterTemplate;
        bool needsCompilation = true;
        string titleTag;

        private ReportBuilder () { }

        public static IReportBuilder<T> Create (string name) {
            return new ReportBuilder<T> { name = name };
        }

        public IReportBuilder<T> WithTemplate (string templateString) {
            template = templateString;
            needsCompilation = true;
            return this;
        }

        public IReportBuilder<T> WithMasterTemplate (string templateString) {
            masterTemplate = templateString;
            needsCompilation = true;
            return this;
        }

        public IReportBuilder<T> WithTemplateFromFileSystem (string templateFile) {
            return WithTemplate (TemplateFinder.GetTemplateFromFileSystem (templateFile));
        }

        public IReportBuilder<T> WithMasterTemplateFromFileSystem (string templateFile) {
            return WithMasterTemplate (TemplateFinder.GetTemplateFromFileSystem (templateFile));
        }

        public IReportBuilder<T> WithTemplateFromResource (string templateFile, Assembly assembly) {
            return WithTemplate (TemplateFinder.GetTemplateFromResource (templateFile, assembly));
        }

        public IReportBuilder<T> WithMasterTemplateFromResource (string templateFile, Assembly assembly) {
            return WithMasterTemplate (TemplateFinder.GetTemplateFromResource (templateFile, assembly));
        }

        public IReportBuilder<T> WithTitle (Expression<Func<T, string>> titleGenerator) {
            var mex = titleGenerator.Body as MemberExpression;
            if (mex != null) {
                titleTag = "@Model." + mex.Member.Name;
                needsCompilation = true;
                return this;
            }

            var mcex = titleGenerator.Body as MethodCallExpression;
            if (mcex != null && mcex.Arguments.Count == 0) {
                titleTag = "@Model." + mcex.Method.Name + "()";
                needsCompilation = true;
                return this;
            }

            throw new InvalidOperationException ("Invalid expression type passed.");
        }

        public string BuildHtml (T model) {
            if (needsCompilation) {
                var templateToUse = PrepareTemplate ();
                Razor.Compile (templateToUse, typeof (T), name);
                needsCompilation = false;
            }

            return Razor.Run<T> (model, name);
        }

        string PrepareTemplate () {
            var output = (string.IsNullOrEmpty (masterTemplate)) ? template : masterTemplate.Replace ("@@BODY", template);
            return output.Replace ("@@TITLE", titleTag);
        }
    }
}<commit_msg>Making recompilation decision a bit smarter (avoiding if same template is set again)<commit_after>﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using RazorEngine;

namespace RazorReport {
    public class ReportBuilder<T> : IReportBuilder<T> {
        string name;
        string template;
        string masterTemplate;
        bool needsCompilation = true;
        string titleTag;

        private ReportBuilder () { }

        public static IReportBuilder<T> Create (string name) {
            return new ReportBuilder<T> { name = name };
        }

        public IReportBuilder<T> WithTemplate (string templateString) {
            needsCompilation = templateString != template;
            template = templateString;
            return this;
        }

        public IReportBuilder<T> WithMasterTemplate (string templateString) {
            needsCompilation = masterTemplate != templateString;
            masterTemplate = templateString;
            return this;
        }

        public IReportBuilder<T> WithTemplateFromFileSystem (string templateFile) {
            return WithTemplate (TemplateFinder.GetTemplateFromFileSystem (templateFile));
        }

        public IReportBuilder<T> WithMasterTemplateFromFileSystem (string templateFile) {
            return WithMasterTemplate (TemplateFinder.GetTemplateFromFileSystem (templateFile));
        }

        public IReportBuilder<T> WithTemplateFromResource (string templateFile, Assembly assembly) {
            return WithTemplate (TemplateFinder.GetTemplateFromResource (templateFile, assembly));
        }

        public IReportBuilder<T> WithMasterTemplateFromResource (string templateFile, Assembly assembly) {
            return WithMasterTemplate (TemplateFinder.GetTemplateFromResource (templateFile, assembly));
        }

        public IReportBuilder<T> WithTitle (Expression<Func<T, string>> titleGenerator) {
            var mex = titleGenerator.Body as MemberExpression;
            if (mex != null) {
                titleTag = "@Model." + mex.Member.Name;
                needsCompilation = true;
                return this;
            }

            var mcex = titleGenerator.Body as MethodCallExpression;
            if (mcex != null && mcex.Arguments.Count == 0) {
                titleTag = "@Model." + mcex.Method.Name + "()";
                needsCompilation = true;
                return this;
            }

            throw new InvalidOperationException ("Invalid expression type passed.");
        }

        public string BuildHtml (T model) {
            if (needsCompilation) {
                var templateToUse = PrepareTemplate ();
                Razor.Compile (templateToUse, typeof (T), name);
                needsCompilation = false;
            }

            return Razor.Run<T> (model, name);
        }

        string PrepareTemplate () {
            var output = (string.IsNullOrEmpty (masterTemplate)) ? template : masterTemplate.Replace ("@@BODY", template);
            return output.Replace ("@@TITLE", titleTag);
        }
    }
}
{'fraction_non_alphanumeric': 0.08226903300713219, 'fraction_numerical': 0.0003317299718029524, 'mean_word_length': 2.2541824069077174, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '214352', 'n_tokens_mistral': 1464, 'n_tokens_neox': 1408, 'n_words': 378}