// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting
{
    public class FormattingEngineTests_Venus : CSharpFormattingEngineTestBase
    {
        public FormattingEngineTests_Venus(ITestOutputHelper output) : base(output) { }

        [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting), Trait(Traits.Feature, Traits.Features.Venus)]
        public async Task SimpleOneLineNugget()
        {
            var code = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1[|
                int x=1 ;
                |]#line hidden
                #line default
                    }
                }
                """;

            var expected = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1
                           int x = 1;
                #line hidden
                #line default
                }
                }
                """;

            await AssertFormatWithBaseIndentAsync(expected, code, baseIndentation: 7);
        }

        [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting), Trait(Traits.Feature, Traits.Features.Venus)]
        public async Task SimpleMultiLineNugget()
        {
            var code = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1[|
                if(true)
                {
                Console.WriteLine(5);}
                |]#line hidden
                #line default
                    }
                }
                """;

            var expected = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1
                       if (true)
                       {
                           Console.WriteLine(5);
                       }
                #line hidden
                #line default
                }
                }
                """;

            await AssertFormatWithBaseIndentAsync(expected, code, baseIndentation: 3);
        }

        [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting), Trait(Traits.Feature, Traits.Features.Venus)]
        public async Task SimpleQueryWithinNugget()
        {
            var code = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1[|
                int[] numbers = {  5,  4,  1  };
                var even =  from     n      in  numbers
                                   where  n %   2 ==   0
                                          select    n;
                |]#line hidden
                #line default
                    }
                }
                """;

            var expected = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1
                           int[] numbers = { 5, 4, 1 };
                           var even = from n in numbers
                                      where n % 2 == 0
                                      select n;
                #line hidden
                #line default
                }
                }
                """;

            await AssertFormatWithBaseIndentAsync(expected, code, baseIndentation: 7);
        }

        [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting), Trait(Traits.Feature, Traits.Features.Venus)]
        public async Task LambdaExpressionInNugget()
        {
            var code = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1[|
                int[] source = new [] {   3,   8, 4,   6, 1, 7, 9, 2, 4, 8} ;

                foreach(int i   in source.Where(x  =>  x  > 5))
                    Console.WriteLine(i);
                |]#line hidden
                #line default
                    }
                }
                """;

            var expected = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1
                       int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

                       foreach (int i in source.Where(x => x > 5))
                           Console.WriteLine(i);
                #line hidden
                #line default
                }
                }
                """;

            await AssertFormatWithBaseIndentAsync(expected, code, baseIndentation: 3);
        }

        [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/576457")]
        [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting), Trait(Traits.Feature, Traits.Features.Venus)]
        public async Task StatementLambdaInNugget()
        {
            var code = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1[|
                       int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

                    foreach (int i in source.Where(
                           x   =>
                           { 
                                if (x <= 3)
                    return true;
                                   else if (x >= 7)
                           return true;
                                   return false;
                               }
                       ))
                            Console.WriteLine(i);
                |]#line hidden
                #line default
                    }
                }
                """;

            var expected = """
                public class Default
                {
                    void PreRender()
                    {
                #line "Goo.aspx", 1
                       int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

                       foreach (int i in source.Where(
                              x =>
                              {
                                  if (x <= 3)
                                      return true;
                                  else if (x >= 7)
                                      return true;
                                  return false;
                              }
                          ))
                           Console.WriteLine(i);
                #line hidden
                #line default
                }
                }
                """;

            // It is somewhat odd that the 'x' and the ')' maintain their
            // position relative to 'foreach', but the block doesn't, but that isn't
            // Venus specific, just the way the formatting engine is.
            await AssertFormatWithBaseIndentAsync(expected, code, baseIndentation: 3);
        }
    }
}
