﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file for additional information.
 * The ASF licenses this file under the Apache License, Version 2.0.
 */

using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Lucene.Net.CodeAnalysis.Dev.Utility;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;

namespace Lucene.Net.CodeAnalysis.Dev.CodeFixes.LuceneDev6xxx
{
    [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6001_6002_StringComparisonCodeFixProvider)), Shared]
    public sealed class LuceneDev6001_6002_StringComparisonCodeFixProvider : CodeFixProvider
    {
        private const string Ordinal = "Ordinal";
        private const string OrdinalIgnoreCase = "OrdinalIgnoreCase";
        private const string TitleOrdinal = "Use StringComparison.Ordinal";
        private const string TitleOrdinalIgnoreCase = "Use StringComparison.OrdinalIgnoreCase";

        public override ImmutableArray<string> FixableDiagnosticIds =>
            ImmutableArray.Create(
                Descriptors.LuceneDev6001_MissingStringComparison.Id,
                Descriptors.LuceneDev6002_InvalidStringComparison.Id);

        public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

        /// <summary>
        /// Registers available code fixes for all diagnostics in the context.
        /// </summary>
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
            if (root == null) return;

            // Iterate over ALL diagnostics in the context to ensure all issues are offered a fix.
            foreach (var diagnostic in context.Diagnostics)
            {
                var invocation = root.FindToken(diagnostic.Location.SourceSpan.Start)
                                     .Parent?
                                     .AncestorsAndSelf()
                                     .OfType<InvocationExpressionSyntax>()
                                     .FirstOrDefault();
                if (invocation == null) continue;

                var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
                if (semanticModel == null) continue;

                // Skip char literals and single-character string literals when safe (LuceneDev6005 handles conversion).
                var firstArgExpr = invocation.ArgumentList.Arguments.FirstOrDefault()?.Expression;
                if (firstArgExpr is LiteralExpressionSyntax lit)
                {
                    if (lit.IsKind(SyntaxKind.CharacterLiteralExpression))
                        continue;

                    if (lit.IsKind(SyntaxKind.StringLiteralExpression) && lit.Token.ValueText.Length == 1)
                    {
                        bool hasStringComparisonArg = invocation.ArgumentList.Arguments.Any(arg =>
                            (semanticModel.GetTypeInfo(arg.Expression).Type is INamedTypeSymbol t &&
                                t.ToDisplayString() == "System.StringComparison")
                            || (semanticModel.GetSymbolInfo(arg.Expression).Symbol is IFieldSymbol f &&
                                f.ContainingType?.ToDisplayString() == "System.StringComparison"));

                        if (!hasStringComparisonArg)
                            continue;
                    }
                }

                // --- Fix Registration Logic ---

                if (diagnostic.Id == Descriptors.LuceneDev6001_MissingStringComparison.Id)
                {
                    // Case 1: Argument is missing. Only offer Ordinal as the safe, conservative default.
                    RegisterFix(context, invocation, Ordinal, TitleOrdinal, diagnostic);
                }
                else if (diagnostic.Id == Descriptors.LuceneDev6002_InvalidStringComparison.Id)
                {
                    // Case 2: Invalid argument is present. Determine the best replacement.
                    if (TryDetermineReplacement(invocation, semanticModel, out string? targetComparison))
                    {
                        var title = (targetComparison!) == Ordinal ? TitleOrdinal : TitleOrdinalIgnoreCase;
                        RegisterFix(context, invocation, targetComparison!, title, diagnostic);
                    }
                    // If TryDetermineReplacement returns false, the argument is an invalid non-constant
                    // expression (e.g., a variable). We skip the fix to avoid arbitrary changes.
                }
            }
        }

        private static void RegisterFix(
            CodeFixContext context,
            InvocationExpressionSyntax invocation,
            string comparisonMember,
            string title,
            Diagnostic diagnostic)
        {
            context.RegisterCodeFix(CodeAction.Create(
                title: title,
                createChangedDocument: c => FixInvocationAsync(context.Document, invocation, comparisonMember, c),
                equivalenceKey: title),
                diagnostic);
        }

        /// <summary>
        /// Determines the appropriate ordinal replacement (Ordinal or OrdinalIgnoreCase)
        /// for an existing culture-sensitive StringComparison argument.
        /// Only operates on constant argument values.
        /// </summary>
        /// <returns>True if a valid replacement was determined, false otherwise (e.g., if argument is non-constant).</returns>
        private static bool TryDetermineReplacement(InvocationExpressionSyntax invocation, SemanticModel semanticModel, out string? targetComparison)
        {
            targetComparison = null;
            var stringComparisonType = semanticModel.Compilation.GetTypeByMetadataName("System.StringComparison");
            var existingArg = invocation.ArgumentList.Arguments.FirstOrDefault(arg =>
                SymbolEqualityComparer.Default.Equals(
                    semanticModel.GetTypeInfo(arg.Expression).Type, stringComparisonType));

            if (existingArg != null)
            {
                var constVal = semanticModel.GetConstantValue(existingArg.Expression);
                if (constVal.HasValue && constVal.Value is int intVal)
                {
                    // Map original comparison to corresponding ordinal variant for constant values
                    switch ((System.StringComparison)intVal)
                    {
                        case System.StringComparison.CurrentCulture:
                        case System.StringComparison.InvariantCulture:
                            targetComparison = Ordinal;
                            return true;
                        case System.StringComparison.CurrentCultureIgnoreCase:
                        case System.StringComparison.InvariantCultureIgnoreCase:
                            targetComparison = OrdinalIgnoreCase;
                            return true;
                        case System.StringComparison.Ordinal:
                        case System.StringComparison.OrdinalIgnoreCase:
                            return false; // Already correct
                    }
                }
                // Argument exists, but is not a constant value (e.g., a variable). We skip the fix.
                return false;
            }

            // Should not be called for missing arguments by the caller.
            return false;
        }

        /// <summary>
        /// Creates the new document by either replacing an existing StringComparison argument
        /// or adding a new one, based on the fix action.
        /// </summary>
        private static async Task<Document> FixInvocationAsync(Document document, InvocationExpressionSyntax invocation, string comparisonMember, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            if (root == null) return document;

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var stringComparisonType = semanticModel?.Compilation.GetTypeByMetadataName("System.StringComparison");

            // 1. Create the new StringComparison argument expression
            var stringComparisonExpr = SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                SyntaxFactory.IdentifierName("StringComparison"),
                SyntaxFactory.IdentifierName(comparisonMember));

            var newArg = SyntaxFactory.Argument(stringComparisonExpr);

            // 2. Find existing argument for replacement/addition check
            var existingArg = invocation.ArgumentList.Arguments.FirstOrDefault(arg =>
                semanticModel != null &&
                SymbolEqualityComparer.Default.Equals(semanticModel.GetTypeInfo(arg.Expression).Type, stringComparisonType));

            // 3. Perform the syntax replacement/addition
            InvocationExpressionSyntax newInvocation;
            if (existingArg != null)
            {
                // Argument exists (Replacement case: InvalidComparison)
                // Preserve leading/trailing trivia (spaces/comma) from the expression being replaced
                var newExprWithTrivia = stringComparisonExpr
                    .WithLeadingTrivia(existingArg.Expression.GetLeadingTrivia())
                    .WithTrailingTrivia(existingArg.Expression.GetTrailingTrivia());

                var newArgWithTrivia = existingArg.WithExpression(newExprWithTrivia);

                newInvocation = invocation.ReplaceNode(existingArg, newArgWithTrivia);
            }
            else
            {
                // Argument is missing (Addition case: MissingComparison)
                // Use AddArguments, relying on Roslyn to correctly handle comma/spacing trivia.
                newInvocation = invocation.WithArgumentList(
                    invocation.ArgumentList.AddArguments(newArg)
                );
            }

            // 4. Update the document root (Ensure using statement is present and replace invocation)
            var newRoot = EnsureSystemUsing(root).ReplaceNode(invocation, newInvocation);
            return document.WithSyntaxRoot(newRoot);
        }

        /// <summary>
        /// Ensures a 'using System;' directive is present in the document.
        /// </summary>
        private static SyntaxNode EnsureSystemUsing(SyntaxNode root)
        {
            if (root is CompilationUnitSyntax compilationUnit)
            {
                var hasSystemUsing = compilationUnit.Usings.Any(u =>
                    u.Name is IdentifierNameSyntax id && id.Identifier.ValueText == "System");

                if (!hasSystemUsing)
                {
                    var systemUsing = SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("System"))
                                                   .WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed);
                    return compilationUnit.AddUsings(systemUsing);
                }
            }

            return root;
        }
    }
}
