<commit_before>﻿using System.Collections.Generic;
using System.Linq;
using Efrpg.Filtering;
using Efrpg.TemplateModels;

namespace Efrpg.Templates
{
    /// <summary>
    /// {{Mustache}} template documentation available at https://github.com/jehugaleahsa/mustache-sharp
    /// </summary>
    public class TemplateEfCore : Template
    {
        public override string Usings()
        {
            return @"
{{#each this}}
using {{this}};{{#newline}}
{{/each}}";
        }

        public override List<string> DatabaseContextInterfaceUsings(InterfaceModel data)
        {
            var usings = new List<string>
            {
                "System",
                "System.Data",
                "System.Threading.Tasks",
                "System.Threading"
            };

            if (Settings.IncludeCodeGeneratedAttribute)
                usings.Add("System.CodeDom.Compiler");

            if (data.tables.Any() || data.hasStoredProcs)
            {
                usings.Add("Microsoft.EntityFrameworkCore");
                usings.Add("Microsoft.EntityFrameworkCore.Infrastructure");
                usings.Add("System.Linq");
            }

            if (data.hasStoredProcs)
                usings.Add("System.Collections.Generic");

            if (!Settings.UseInheritedBaseInterfaceFunctions)
            {
                usings.Add("System.Collections.Generic");
            }

            return usings;
        }

        public override string DatabaseContextInterface()
        {
            return @"
{{interfaceModifier}} interface {{DbContextInterfaceName}} : {{DbContextInterfaceBaseClasses}}{{#newline}}
{{{#newline}}

{{#each tables}}
    DbSet<{{DbSetName}}> {{PluralTableName}} { get; set; }{{Comment}}{{#newline}}
{{/each}}

{{#if AdditionalContextInterfaceItems}}
{{#newline}}
    // Additional interface items{{#newline}}
{{/if}}
{{#each AdditionalContextInterfaceItems}}
    {{this}}{{#newline}}
{{/each}}


{{#if addSaveChanges}}
{{#newline}}
    int SaveChanges();{{#newline}}
    int SaveChanges(bool acceptAllChangesOnSuccess);{{#newline}}
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));{{#newline}}
    Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken));{{#newline}}
    DatabaseFacade Database { get; }{{#newline}}
    DbSet<TEntity> Set<TEntity>() where TEntity : class;{{#newline}}
    string ToString();{{#newline}}
{{/if}}


{{#if hasStoredProcs}}
{{#newline}}
    // Stored Procedures{{#newline}}
{{#each storedProcs}}
{{#if HasReturnModels}}

{{#if MultipleReturnModels}}
    // {{ReturnType}} {{FunctionName}}({{WriteStoredProcFunctionParamsFalse}}); Cannot be created as EF Core does not yet support stored procedures with multiple result sets.{{#newline}}
{{#else}}
    {{ReturnType}} {{FunctionName}}({{WriteStoredProcFunctionParamsFalse}});{{#newline}}
{{/if}}
{{#if SingleReturnModel}}
    {{ReturnType}} {{FunctionName}}({{WriteStoredProcFunctionParamsTrue}});{{#newline}}
{{/if}}
{{#else}}
    int {{FunctionName}}({{WriteStoredProcFunctionParamsTrue}});{{#newline}}
{{/if}}

{{#if AsyncFunctionCannotBeCreated}}
    // {{FunctionName}}Async() cannot be created due to having out parameters, or is relying on the procedure result ({{ReturnType}}){{#newline}}
{{#else}}
{{#if MultipleReturnModels}}
    // Task<{{ReturnType}}> {{FunctionName}}Async({{WriteStoredProcFunctionParamsFalse}}); Cannot be created as EF Core does not yet support stored procedures with multiple result sets.{{#newline}}
{{#else}}
    Task<{{ReturnType}}> {{FunctionName}}Async({{WriteStoredProcFunctionParamsFalse}});{{#newline}}
{{/if}}
{{/if}}
{{#newline}}
{{/each}}
{{/if}}

{{#if hasTableValuedFunctions}}
{{#newline}}
    // Table Valued Functions{{#newline}}
{{#each tableValuedFunctions}}
    IQueryable<{{ReturnClassName}}> {{ExecName}}({{WriteStoredProcFunctionParamsFalse}}); // {{Schema}}.{{Name}}{{#newline}}
{{/each}}
{{/if}}

{{#if hasScalarValuedFunctions}}
{{#newline}}
    // Scalar Valued Functions{{#newline}}
{{#each scalarValuedFunctions}}
    {{ReturnType}} {{ExecName}}({{WriteStoredProcFunctionParamsFalse}}); // {{Schema}}.{{Name}}{{#newline}}
{{/each}}
{{/if}}

}";
        }

        public override List<string> DatabaseContextUsings(ContextModel data)
        {
            var usings = new List<string>
            {
                "System",
                "System.Data",
                Settings.IsEfCore3Plus() ? "Microsoft.Data.SqlClient" : "System.Data.SqlClient",
                "System.Data.SqlTypes",
                "Microsoft.EntityFrameworkCore",
                "System.Threading.Tasks",
                "System.Threading"
            };

            if (Settings.IncludeCodeGeneratedAttribute)
                usings.Add("System.CodeDom.Compiler");

            if (data.tables.Any() || data.hasStoredProcs)
            {
                usings.Add("System.Linq");
            }

            if (data.hasStoredProcs)
                usings.Add("System.Collections.Generic");

            if(Settings.OnConfiguration == OnConfiguration.Configuration)
                usings.Add("Microsoft.Extensions.Configuration");

            if (!Settings.UseInheritedBaseInterfaceFunctions)
            {
                usings.Add("System.Collections.Generic");
            }

            return usings;
        }

        public override string DatabaseContext()
        {
            return @"
{{DbContextClassModifiers}} class {{DbContextName}} : {{DbContextBaseClass}}{{contextInterface}}{{#newline}}
{{{#newline}}
{{#if OnConfigurationUsesConfiguration}}
    private readonly IConfiguration _configuration;{{#newline}}{{#newline}}
{{/if}}

    public {{DbContextName}}(){{#newline}}
    {{{#newline}}
{{#if DbContextClassIsPartial}}
        InitializePartial();{{#newline}}
{{/if}}
    }{{#newline}}{{#newline}}

    public {{DbContextName}}(DbContextOptions<{{DbContextName}}> options){{#newline}}
        : base(options){{#newline}}
    {{{#newline}}
{{#if DbContextClassIsPartial}}
        InitializePartial();{{#newline}}
{{/if}}
    }{{#newline}}{{#newline}}

{{#if OnConfigurationUsesConfiguration}}
    public {{DbContextName}}(IConfiguration configuration){{#newline}}
    {{{#newline}}
        _configuration = configuration;{{#newline}}
{{#if DbContextClassIsPartial}}
        InitializePartial();{{#newline}}
{{/if}}
    }{{#newline}}{{#newline}}
{{/if}}

{{#each tables}}
    {{DbSetModifier}} DbSet<{{DbSetName}}> {{PluralTableName}} { get; set; }{{Comment}}{{#newline}}
{{/each}}
{{#newline}}

{{#if OnConfigurationUsesConfiguration}}
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){{#newline}}
    {{{#newline}}
        if (!optionsBuilder.IsConfigured && _configuration != null){{#newline}}
        {{{#newline}}<commit_msg>Allowing removal of parameterless constructor<commit_after>﻿using System.Collections.Generic;
using System.Linq;
using Efrpg.Filtering;
using Efrpg.TemplateModels;

namespace Efrpg.Templates
{
    /// <summary>
    /// {{Mustache}} template documentation available at https://github.com/jehugaleahsa/mustache-sharp
    /// </summary>
    public class TemplateEfCore : Template
    {
        public override string Usings()
        {
            return @"
{{#each this}}
using {{this}};{{#newline}}
{{/each}}";
        }

        public override List<string> DatabaseContextInterfaceUsings(InterfaceModel data)
        {
            var usings = new List<string>
            {
                "System",
                "System.Data",
                "System.Threading.Tasks",
                "System.Threading"
            };

            if (Settings.IncludeCodeGeneratedAttribute)
                usings.Add("System.CodeDom.Compiler");

            if (data.tables.Any() || data.hasStoredProcs)
            {
                usings.Add("Microsoft.EntityFrameworkCore");
                usings.Add("Microsoft.EntityFrameworkCore.Infrastructure");
                usings.Add("System.Linq");
            }

            if (data.hasStoredProcs)
                usings.Add("System.Collections.Generic");

            if (!Settings.UseInheritedBaseInterfaceFunctions)
            {
                usings.Add("System.Collections.Generic");
            }

            return usings;
        }

        public override string DatabaseContextInterface()
        {
            return @"
{{interfaceModifier}} interface {{DbContextInterfaceName}} : {{DbContextInterfaceBaseClasses}}{{#newline}}
{{{#newline}}

{{#each tables}}
    DbSet<{{DbSetName}}> {{PluralTableName}} { get; set; }{{Comment}}{{#newline}}
{{/each}}

{{#if AdditionalContextInterfaceItems}}
{{#newline}}
    // Additional interface items{{#newline}}
{{/if}}
{{#each AdditionalContextInterfaceItems}}
    {{this}}{{#newline}}
{{/each}}


{{#if addSaveChanges}}
{{#newline}}
    int SaveChanges();{{#newline}}
    int SaveChanges(bool acceptAllChangesOnSuccess);{{#newline}}
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));{{#newline}}
    Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken));{{#newline}}
    DatabaseFacade Database { get; }{{#newline}}
    DbSet<TEntity> Set<TEntity>() where TEntity : class;{{#newline}}
    string ToString();{{#newline}}
{{/if}}


{{#if hasStoredProcs}}
{{#newline}}
    // Stored Procedures{{#newline}}
{{#each storedProcs}}
{{#if HasReturnModels}}

{{#if MultipleReturnModels}}
    // {{ReturnType}} {{FunctionName}}({{WriteStoredProcFunctionParamsFalse}}); Cannot be created as EF Core does not yet support stored procedures with multiple result sets.{{#newline}}
{{#else}}
    {{ReturnType}} {{FunctionName}}({{WriteStoredProcFunctionParamsFalse}});{{#newline}}
{{/if}}
{{#if SingleReturnModel}}
    {{ReturnType}} {{FunctionName}}({{WriteStoredProcFunctionParamsTrue}});{{#newline}}
{{/if}}
{{#else}}
    int {{FunctionName}}({{WriteStoredProcFunctionParamsTrue}});{{#newline}}
{{/if}}

{{#if AsyncFunctionCannotBeCreated}}
    // {{FunctionName}}Async() cannot be created due to having out parameters, or is relying on the procedure result ({{ReturnType}}){{#newline}}
{{#else}}
{{#if MultipleReturnModels}}
    // Task<{{ReturnType}}> {{FunctionName}}Async({{WriteStoredProcFunctionParamsFalse}}); Cannot be created as EF Core does not yet support stored procedures with multiple result sets.{{#newline}}
{{#else}}
    Task<{{ReturnType}}> {{FunctionName}}Async({{WriteStoredProcFunctionParamsFalse}});{{#newline}}
{{/if}}
{{/if}}
{{#newline}}
{{/each}}
{{/if}}

{{#if hasTableValuedFunctions}}
{{#newline}}
    // Table Valued Functions{{#newline}}
{{#each tableValuedFunctions}}
    IQueryable<{{ReturnClassName}}> {{ExecName}}({{WriteStoredProcFunctionParamsFalse}}); // {{Schema}}.{{Name}}{{#newline}}
{{/each}}
{{/if}}

{{#if hasScalarValuedFunctions}}
{{#newline}}
    // Scalar Valued Functions{{#newline}}
{{#each scalarValuedFunctions}}
    {{ReturnType}} {{ExecName}}({{WriteStoredProcFunctionParamsFalse}}); // {{Schema}}.{{Name}}{{#newline}}
{{/each}}
{{/if}}

}";
        }

        public override List<string> DatabaseContextUsings(ContextModel data)
        {
            var usings = new List<string>
            {
                "System",
                "System.Data",
                Settings.IsEfCore3Plus() ? "Microsoft.Data.SqlClient" : "System.Data.SqlClient",
                "System.Data.SqlTypes",
                "Microsoft.EntityFrameworkCore",
                "System.Threading.Tasks",
                "System.Threading"
            };

            if (Settings.IncludeCodeGeneratedAttribute)
                usings.Add("System.CodeDom.Compiler");

            if (data.tables.Any() || data.hasStoredProcs)
            {
                usings.Add("System.Linq");
            }

            if (data.hasStoredProcs)
                usings.Add("System.Collections.Generic");

            if(Settings.OnConfiguration == OnConfiguration.Configuration)
                usings.Add("Microsoft.Extensions.Configuration");

            if (!Settings.UseInheritedBaseInterfaceFunctions)
            {
                usings.Add("System.Collections.Generic");
            }

            return usings;
        }

        public override string DatabaseContext()
        {
            return @"
{{DbContextClassModifiers}} class {{DbContextName}} : {{DbContextBaseClass}}{{contextInterface}}{{#newline}}
{{{#newline}}
{{#if OnConfigurationUsesConfiguration}}
    private readonly IConfiguration _configuration;{{#newline}}{{#newline}}
{{/if}}

{{#if AddParameterlessConstructorToDbContext}}
    public {{DbContextName}}(){{#newline}}
    {{{#newline}}
{{#if DbContextClassIsPartial}}
        InitializePartial();{{#newline}}
{{/if}}
    }{{#newline}}{{#newline}}
{{/if}}

    public {{DbContextName}}(DbContextOptions<{{DbContextName}}> options){{#newline}}
        : base(options){{#newline}}
    {{{#newline}}
{{#if DbContextClassIsPartial}}
        InitializePartial();{{#newline}}
{{/if}}
    }{{#newline}}{{#newline}}

{{#if OnConfigurationUsesConfiguration}}
    public {{DbContextName}}(IConfiguration configuration){{#newline}}
    {{{#newline}}
        _configuration = configuration;{{#newline}}
{{#if DbContextClassIsPartial}}
        InitializePartial();{{#newline}}
{{/if}}
    }{{#newline}}{{#newline}}
{{/if}}

{{#each tables}}
    {{DbSetModifier}} DbSet<{{DbSetName}}> {{PluralTableName}} { get; set; }{{Comment}}{{#newline}}
{{/each}}
{{#newline}}

{{#if OnConfigurationUsesConfiguration}}
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){{#newline}}
    {{{#newline}}
        if (!optionsBuilder.IsConfigured && _configuration != null){{#newline}}
        {{{#newline}}
{'fraction_non_alphanumeric': 0.16877393251932662, 'fraction_numerical': 0.00014449822989668376, 'mean_word_length': 3.3734597156398105, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 2, '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': '654798', 'n_tokens_mistral': 4018, 'n_tokens_neox': 3918, 'n_words': 702}