using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Text;

namespace BD.WTTS.Generators;

[Generator]
public class SettingsGenerator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        // retreive the populated receiver 
        if (!(context.SyntaxReceiver is SettingsGenerationReceiver receiver))
            return;

        var compilation = context.Compilation;

        // loop over the candidate fields, and keep the ones that are actually annotated
        var symbols = new List<ITypeSymbol>();
        foreach (var decl in receiver.Candidates)
        {
            var model = compilation.GetSemanticModel(decl.SyntaxTree);
            if (model.GetDeclaredSymbol(decl, context.CancellationToken) is ITypeSymbol symbol)
            {
                symbols.Add(symbol);
            }
        }

        foreach (var symbol in symbols)
        {
            var code = new StringBuilder();
            // Build up the source code
            //string source = $@"// <auto-generated/>

            //";
            // 遍历 settings 类型的所有属性。
            foreach (var field in symbol.GetMembers().OfType<IFieldSymbol>())
            {
                // 获取属性名和属性类型。
                var propertyName = field.Name;
                var propertyType = field.Type.ToDisplayString();

                // 生成代码，打印属性值。
                code.AppendLine($"// \"{propertyName}: {0}\", type:{propertyType}");
            }
            context.AddSource($"{symbol.Name}.g.cs", SourceText.From(code.ToString(), Encoding.UTF8));
        }

        //foreach (var syntaxTree in context.Compilation.SyntaxTrees)
        //{
        //    var model = context.Compilation.GetSemanticModel(syntaxTree);

        //    var classDeclarations = syntaxTree.GetRoot()
        //        .DescendantNodes().OfType<ClassDeclarationSyntax>();

        //    foreach (var classDeclaration in classDeclarations)
        //    {
        //        var classSymbol = model.GetDeclaredSymbol(classDeclaration);
        //        if (classSymbol == null) continue;

        //        var attributeData = classSymbol.GetAttributes().FirstOrDefault(ad => ad.AttributeClass?.ToDisplayString() == SettingsGenerationReceiver.AttributeName);
        //        if (attributeData == null) continue;

        //        context.Compilation.GetTypeByMetadataName("YourNamespace.Settings");

        //        // 遍历 settings 类型的所有属性。
        //        foreach (var property in classSymbol.ContainingType.GetMembers().OfType<IPropertySymbol>())
        //        {
        //            // 获取属性名和属性类型。
        //            var propertyName = property.Name;
        //            var propertyType = property.Type.ToDisplayString();

        //            // 生成代码，打印属性值。
        //            var code = $"Console.WriteLine(\"{propertyName}: {{0}}\", settings.{propertyName});";
        //            context.AddSource($"{propertyName}.g.cs", code);
        //        }
        //    }
        //}

        //// Find the main method
        //var mainMethod = context.Compilation.GetEntryPoint(context.CancellationToken);

        //// Build up the source code
        //string source = $@"// <auto-generated/>
        //using System;

        //namespace {mainMethod.ContainingNamespace.ToDisplayString()}
        //{{
        //    public static partial class {mainMethod.ContainingType.Name}
        //    {{
        //        static partial void HelloFrom(string name) =>
        //            Console.WriteLine($""Generator says: Hi from '{{name}}'"");
        //    }}
        //}}
        //";
        //var typeName = mainMethod.ContainingType.Name;

        //// Add the source code to the compilation
        //context.AddSource($"{typeName}.g.cs", source);
    }

    public void Initialize(GeneratorInitializationContext context)
    {
        // No initialization required for this
        context.RegisterForSyntaxNotifications(() => new SettingsGenerationReceiver());
    }
}