/*
 * 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.
 */

/*
 * 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;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Lucene.Net.CodeAnalysis.Dev.CodeFixes.LuceneDev2xxx
{
    [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev2000_2001_2002_2004_AddInvariantCultureCodeFixProvider)), Shared]
    public sealed class LuceneDev2000_2001_2002_2004_AddInvariantCultureCodeFixProvider : CodeFixProvider
    {
        private const string TitleInvariant = "Add CultureInfo.InvariantCulture";
        private const string TitleCurrent = "Add CultureInfo.CurrentCulture";

        public override ImmutableArray<string> FixableDiagnosticIds =>
            ImmutableArray.Create(
                Descriptors.LuceneDev2000_BclNumericParseMissingFormatProvider.Id,
                Descriptors.LuceneDev2001_BclNumericToStringMissingFormatProvider.Id,
                Descriptors.LuceneDev2002_ConvertNumericMissingFormatProvider.Id,
                Descriptors.LuceneDev2004_J2NNumericMissingFormatProvider.Id);

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

        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
            if (root is null) return;

            foreach (var diagnostic in context.Diagnostics)
            {
                var invocation = root.FindToken(diagnostic.Location.SourceSpan.Start)
                                     .Parent?
                                     .AncestorsAndSelf()
                                     .OfType<InvocationExpressionSyntax>()
                                     .FirstOrDefault();
                if (invocation is null) continue;

                RegisterFix(context, invocation, "InvariantCulture", TitleInvariant, diagnostic);
                RegisterFix(context, invocation, "CurrentCulture", TitleCurrent, diagnostic);
            }
        }

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

        private static async Task<Document> AddCultureArgumentAsync(
            Document document,
            InvocationExpressionSyntax invocation,
            string cultureMember,
            CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            if (root is null) return document;

            var cultureExpr = SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                SyntaxFactory.IdentifierName("CultureInfo"),
                SyntaxFactory.IdentifierName(cultureMember));
            var newArg = SyntaxFactory.Argument(cultureExpr);

            // For TryParse-style methods, the IFormatProvider must come BEFORE the trailing
            // `out` argument: bool TryParse(string, IFormatProvider, out T). Otherwise append.
            var args = invocation.ArgumentList.Arguments;
            int insertAt = args.Count;
            if (args.Count > 0 && args[args.Count - 1].RefKindKeyword.IsKind(SyntaxKind.OutKeyword))
                insertAt = args.Count - 1;

            var newArgs = args.Insert(insertAt, newArg);
            var newInvocation = invocation.WithArgumentList(invocation.ArgumentList.WithArguments(newArgs));
            var newRoot = EnsureGlobalizationUsing(root).ReplaceNode(invocation, newInvocation);
            return document.WithSyntaxRoot(newRoot);
        }

        internal static SyntaxNode EnsureGlobalizationUsing(SyntaxNode root)
        {
            if (root is CompilationUnitSyntax compilationUnit)
            {
                var hasUsing = compilationUnit.Usings.Any(u => u.Name?.ToString() == "System.Globalization");
                if (!hasUsing)
                {
                    // Match the document's existing line ending so the inserted using directive
                    // doesn't mix CRLF and LF (the .gitattributes for this repo enforces CRLF
                    // for *.cs, but local checkouts may differ).
                    var newline = DetectLineEnding(root);
                    var usingDirective = SyntaxFactory.UsingDirective(
                        SyntaxFactory.QualifiedName(
                            SyntaxFactory.IdentifierName("System"),
                            SyntaxFactory.IdentifierName("Globalization")))
                        .WithTrailingTrivia(SyntaxFactory.ElasticEndOfLine(newline));
                    return compilationUnit.AddUsings(usingDirective);
                }
            }
            return root;
        }

        private static string DetectLineEnding(SyntaxNode root)
        {
            var text = root.GetText();
            if (text.Lines.Count > 1)
            {
                var firstLine = text.Lines[0];
                var endIncludingBreak = text.Lines[1].Start;
                var breakLength = endIncludingBreak - firstLine.End;
                if (breakLength == 2) return "\r\n";
                if (breakLength == 1)
                {
                    var ch = text[firstLine.End];
                    if (ch == '\r') return "\r";
                    return "\n";
                }
            }
            return "\n";
        }
    }
}
