﻿// 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;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.KeywordHighlighting.KeywordHighlighters;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
{
    [Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
    public class LoopHighlighterTests : AbstractCSharpKeywordHighlighterTests
    {
        internal override Type GetHighlighterType()
            => typeof(LoopHighlighter);

        [Fact]
        public async Task TestExample1_1()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        {|Cursor:[|while|]|} (true)
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample1_2()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|while|] (true)
        {
            if (x)
            {
                {|Cursor:[|break|]|};
            }
            else
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample1_3()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|while|] (true)
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                {|Cursor:[|continue|]|};
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample2_1()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        {|Cursor:[|do|]|}
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                [|continue|];
            }
        }
        [|while|] (true);
    }
}");
        }

        [Fact]
        public async Task TestExample2_2()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|do|]
        {
            if (x)
            {
                {|Cursor:[|break|]|};
            }
            else
            {
                [|continue|];
            }
        }
        [|while|] (true);
    }
}");
        }

        [Fact]
        public async Task TestExample2_3()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|do|]
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                {|Cursor:[|continue|]|};
            }
        }
        [|while|] (true);
    }
}");
        }

        [Fact]
        public async Task TestExample2_4()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|do|]
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                [|continue|];
            }
        }
        {|Cursor:[|while|]|} (true);
    }
}");
        }

        [Fact]
        public async Task TestExample2_5()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        do
        {
            if (x)
            {
                break;
            }
            else
            {
                continue;
            }
        }
        while {|Cursor:(true)|};
    }
}");
        }

        [Fact]
        public async Task TestExample2_6()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|do|]
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                [|continue|];
            }
        }
        [|while|] (true);{|Cursor:|}
    }
}");
        }

        [Fact]
        public async Task TestExample3_1()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        {|Cursor:[|for|]|} (int i = 0; i < 10; i++)
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample3_2()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|for|] (int i = 0; i < 10; i++)
        {
            if (x)
            {
                {|Cursor:[|break|];|}
            }
            else
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample3_3()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|for|] (int i = 0; i < 10; i++)
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                {|Cursor:[|continue|];|}
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample4_1()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        {|Cursor:[|foreach|]|} (var a in x)
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample4_2()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|foreach|] (var a in x)
        {
            if (x)
            {
                {|Cursor:[|break|];|}
            }
            else
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestExample4_3()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|foreach|] (var a in x)
        {
            if (x)
            {
                [|break|];
            }
            else
            {
                {|Cursor:[|continue|];|}
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_1()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        {|Cursor:[|foreach|]|} (var a in x)
        {
            if (a)
            {
                [|break|];
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            do
                            {
                                break;
                            }
                            while (false);
                            break;
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_2()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|foreach|] (var a in x)
        {
            if (a)
            {
                {|Cursor:[|break|];|}
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            do
                            {
                                break;
                            }
                            while (false);
                            break;
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_3()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            {|Cursor:[|do|]|}
                            {
                                [|break|];
                            }
                            [|while|] (false);
                            break;
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_4()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            [|do|]
                            {
                                {|Cursor:[|break|];|}
                            }
                            [|while|] (false);
                            break;
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_5()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            [|do|]
                            {
                                [|break|];
                            }
                            {|Cursor:[|while|]|} (false);
                            break;
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_6()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            [|do|]
                            {
                                [|break|];
                            }
                            [|while|] (false);{|Cursor:|}
                            break;
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_7()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        {|Cursor:[|while|]|} (true)
                        {
                            do
                            {
                                break;
                            }
                            while (false);
                            [|break|];
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_8()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        [|while|] (true)
                        {
                            do
                            {
                                break;
                            }
                            while (false);
                            {|Cursor:[|break|];|}
                        }

                        break;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                break;
            }
        }
    }
}");
        }

        // TestNestedExample1 9-13 are in SwitchStatementHighlighterTests.cs

        [Fact]
        public async Task TestNestedExample1_14()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            do
                            {
                                break;
                            }
                            while (false);
                            break;
                        }

                        break;
                }
            }

            {|Cursor:[|for|]|} (int i = 0; i < 10; i++)
            {
                [|break|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample1_15()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                break;
            }
            else
            {
                switch (b)
                {
                    case 0:
                        while (true)
                        {
                            do
                            {
                                break;
                            }
                            while (false);
                            break;
                        }

                        break;
                }
            }

            [|for|] (int i = 0; i < 10; i++)
            {
                {|Cursor:[|break|];|}
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_1()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        {|Cursor:[|foreach|]|} (var a in x)
        {
            if (a)
            {
                [|continue|];
            }
            else
            {
                while (true)
                {
                    do
                    {
                        continue;
                    }
                    while (false);
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_2()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        [|foreach|] (var a in x)
        {
            if (a)
            {
                {|Cursor:[|continue|];|}
            }
            else
            {
                while (true)
                {
                    do
                    {
                        continue;
                    }
                    while (false);
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_3()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    {|Cursor:[|do|]|}
                    {
                        [|continue|];
                    }
                    [|while|] (false);
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_4()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    [|do|]
                    {
                        {|Cursor:[|continue|];|}
                    }
                    [|while|] (false);
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_5()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    [|do|]
                    {
                        [|continue|];
                    }
                    {|Cursor:[|while|]|} (false);
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_6()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    do
                    {
                        continue;
                    }
                    while {|Cursor:(false)|};
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_7()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    [|do|]
                    {
                        [|continue|];
                    }
                    [|while|] (false);{|Cursor:|}
                    continue;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_8()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                {|Cursor:[|while|]|} (true)
                {
                    do
                    {
                        continue;
                    }
                    while (false);
                    [|continue|];
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_9()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                [|while|] (true)
                {
                    do
                    {
                        continue;
                    }
                    while (false);
                    {|Cursor:[|continue|];|}
                }
            }

            for (int i = 0; i < 10; i++)
            {
                continue;
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_10()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    do
                    {
                        continue;
                    }
                    while (false);
                    continue;
                }
            }

            {|Cursor:[|for|]|} (int i = 0; i < 10; i++)
            {
                [|continue|];
            }
        }
    }
}");
        }

        [Fact]
        public async Task TestNestedExample2_11()
        {
            await TestAsync(
@"class C
{
    void M()
    {
        foreach (var a in x)
        {
            if (a)
            {
                continue;
            }
            else
            {
                while (true)
                {
                    do
                    {
                        continue;
                    }
                    while (false);
                    continue;
                }
            }

            [|for|] (int i = 0; i < 10; i++)
            {
                {|Cursor:[|continue|];|}
            }
        }
    }
}");
        }
    }
}
