// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text;
using System.Windows.Forms.Analyzers;

namespace System.Windows.Forms.CSharp.Generators.ApplicationConfiguration;

internal static class ApplicationConfigurationInitializeBuilder
{
    public static string GenerateInitialize(string? projectNamespace, ApplicationConfig projectConfig)
    {
        bool topLevelApp = string.IsNullOrWhiteSpace(projectNamespace);
        string? defaultFont = projectConfig.DefaultFont?.ToString();
        string indent = topLevelApp ? string.Empty : "    ";
        return string.Format(topLevelApp ? TopLevelStatements : BoilerPlate,
                             topLevelApp ? string.Empty : projectNamespace,
                             GenerateCode(projectConfig, defaultFont, $"{indent}    ///  "),
                             GenerateCode(projectConfig, defaultFont, $"{indent}        "));

        static string GenerateCode(ApplicationConfig projectConfig, string? defaultFont, string indent)
        {
            StringBuilder code = new();
            const string qualifier = "global::System.Windows.Forms.Application.";
            if (projectConfig.EnableVisualStyles)
            {
                code.Append($"{indent}{qualifier}EnableVisualStyles();\r\n");
            }

            code.Append($"{indent}{qualifier}SetCompatibleTextRenderingDefault({projectConfig.UseCompatibleTextRendering.ToString().ToLowerInvariant()});\r\n");

            code.Append($"{indent}{qualifier}SetHighDpiMode(HighDpiMode.{projectConfig.HighDpiMode});\r\n");

            // Note: we need to set the font _after_ we set the DPI scaling, as it affects how we scale the font.
            if (!string.IsNullOrWhiteSpace(defaultFont))
            {
                code.Append($"{indent}{qualifier}SetDefaultFont({defaultFont});\r\n");
            }

            // Don't append line as we don't need the trailing \r\n!
            code.Remove(code.Length - "\r\n".Length, "\r\n".Length);

            return code.ToString();
        }
    }

    private const string BoilerPlate = @"// <auto-generated />

using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

namespace {0}
{{
    /// <summary>
    ///  Bootstrap the application configuration.
    /// </summary>
    [CompilerGenerated]
    internal static partial class ApplicationConfiguration
    {{
        /// <summary>
        ///  Bootstrap the application as follows:
        ///  <code>
{1}
        /// </code>
        /// </summary>
        public static void Initialize()
        {{
{2}
        }}
    }}
}}
";

    private const string TopLevelStatements = @"// <auto-generated />

using System.Drawing;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows.Forms;
{0}
/// <summary>
///  Bootstrap the application configuration.
/// </summary>
[CompilerGenerated]
internal static partial class ApplicationConfiguration
{{
    /// <summary>
    ///  Bootstrap the application as follows:
    ///  <code>
{1}
    /// </code>
    /// </summary>
    public static void Initialize()
    {{
{2}
    }}
}}
";
}
