﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

namespace Lucene.Net.CodeAnalysis.Dev.CodeFixes
{
    [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev1001_FloatingPointFormattingCSCodeFixProvider)), Shared]
    public class LuceneDev1001_FloatingPointFormattingCSCodeFixProvider : CodeFixProvider
    {
        public override ImmutableArray<string> FixableDiagnosticIds =>
            [Descriptors.LuceneDev1001_FloatingPointFormatting.Id];

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

        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic? diagnostic = context.Diagnostics.FirstOrDefault();
            if (diagnostic is null)
                return;

            SyntaxNode? root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
            if (root is null)
                return;

            // the diagnostic in the analyzer is reported on the member access (e.g. "x.ToString")
            // but we need the whole invocation (e.g. "x.ToString(...)").  So find the invocation
            // by walking ancestors if needed.
            SyntaxNode? node = root.FindNode(diagnostic.Location.SourceSpan);
            if (node is null)
                return;

            if (node is not ExpressionSyntax exprNode)
                return;

            SemanticModel? semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
            if (semanticModel is null)
                return;

            if (!TryGetJ2NTypeAndMember(semanticModel, exprNode, out var j2nTypeName, out var memberAccess))
                return;

            string codeElement = $"J2N.Numerics.{j2nTypeName}.ToString(...)";

            context.RegisterCodeFix(
                CodeActionHelper.CreateFromResource(
                    CodeFixResources.UseX,
                    c => ReplaceWithJ2NToStringAsync(context.Document, memberAccess, c),
                    "UseJ2NToString",
                    codeElement),
                diagnostic);
        }

        private async Task<Document> ReplaceWithJ2NToStringAsync(
            Document document,
            MemberAccessExpressionSyntax memberAccess,
            CancellationToken cancellationToken)
        {
            SemanticModel? semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (semanticModel is null)
                return document;

            if (!TryGetJ2NTypeAndMember(semanticModel, memberAccess, out var j2nTypeName, out _))
                return document;

            // Build J2N.Numerics.Single/Double.ToString
            MemberAccessExpressionSyntax j2nToStringAccess = SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.IdentifierName("J2N"),
                    SyntaxFactory.IdentifierName("Numerics")),
                SyntaxFactory.IdentifierName(j2nTypeName))
                .WithAdditionalAnnotations(Formatter.Annotation);

            MemberAccessExpressionSyntax fullAccess = SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                j2nToStringAccess,
                SyntaxFactory.IdentifierName("ToString"));

            // Build invocation: J2N.Numerics.<Single|Double>.ToString(<expr>, <original args...>)
            if (memberAccess.Parent is not InvocationExpressionSyntax invocation)
                return document;

            var newArgs = new List<ArgumentSyntax> { SyntaxFactory.Argument(memberAccess.Expression) };
            if (invocation.ArgumentList != null)
                newArgs.AddRange(invocation.ArgumentList.Arguments);

            InvocationExpressionSyntax newInvocation = SyntaxFactory.InvocationExpression(
                fullAccess,
                SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(newArgs)))
                .WithTriviaFrom(invocation) // safe now
                .WithAdditionalAnnotations(Formatter.Annotation);

            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
            editor.ReplaceNode(memberAccess.Parent, newInvocation);

            return editor.GetChangedDocument();
        }

        private static bool TryGetJ2NTypeAndMember(
            SemanticModel semanticModel,
            ExpressionSyntax expr,
            out string j2nTypeName,
            out MemberAccessExpressionSyntax memberAccess)
        {
            memberAccess = expr as MemberAccessExpressionSyntax
                ?? expr.AncestorsAndSelf().OfType<MemberAccessExpressionSyntax>().FirstOrDefault();

            if (memberAccess is null)
            {
                j2nTypeName = null!; // we always return false when the value is null, so we can ignore it here.
                return false;
            }

            var typeInfo = semanticModel.GetTypeInfo(memberAccess.Expression);
            var type = typeInfo.Type;

            j2nTypeName = type?.SpecialType switch
            {
                SpecialType.System_Single => "Single",
                SpecialType.System_Double => "Double",
                _ => null! // we always return false when the value is null, so we can ignore it here.
            };

            if (j2nTypeName is null)
                return false;

            return true;
        }
    }
}
