// 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;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.IntelliSense.CompletionSetSources;

[Trait(Traits.Feature, Traits.Features.Completion)]
public sealed class IsPossibleDeconstructionDesignationTests : AbstractContextTests
{
    protected override void CheckResult(bool expected, int position, SyntaxTree syntaxTree)
    {
        var actual = syntaxTree.IsPossibleDeconstructionDesignation(position, CancellationToken.None);
        Assert.Equal(expected, actual);
    }

    [Fact]
    public void Test1()
        => VerifyTrue(AddInsideMethod(@"(var $$, var y)"));

    [Fact]
    public void WellFormed1()
        => VerifyTrue(AddInsideMethod(@"(var $$, var y) = e;"));

    [Fact]
    public void Test2()
        => VerifyTrue(AddInsideMethod(@"(var x, var $$)"));

    [Fact]
    public void Test3()
        => VerifyTrue(AddInsideMethod(@"var ($$, y)"));

    [Fact]
    public void Test4()
        => VerifyTrue(AddInsideMethod(@"var ($$, y)"));

    [Fact]
    public void Test5()
        => VerifyTrue(AddInsideMethod(@"var ($$)"));

    [Fact]
    public void Test6()
        => VerifyTrue(AddInsideMethod(@"(var $$)"));

    [Fact]
    public void Test7()
        => VerifyTrue(AddInsideMethod(@"(var a, var $$)"));

    [Fact]
    public void Test8()
        => VerifyFalse(AddInsideMethod(@"var str = (($$)items) as string;"));

    [Fact]
    public void Test9()
        => VerifyTrue(AddInsideMethod(@"Func<int, int, int> f = (x, i $$"));

    [Fact]
    public void TestNestedVar()
        => VerifyTrue(AddInsideMethod(@"var (($$), y)"));

    [Fact]
    public void TestNestedVar2()
        => VerifyTrue(AddInsideMethod(@"var ((x, $$), y)"));

    [Fact]
    public void TestNestedVar3()
        => VerifyTrue(AddInsideMethod(@"var ((x, $$), y) = e;"));

    [Fact]
    public void TestForeachVar1()
        => VerifyTrue(AddInsideMethod(@"foreach(var ($$"));

    [Fact]
    public void TestForeachVar2()
        => VerifyTrue(AddInsideMethod(@"foreach(var ($$)"));

    [Fact]
    public void TestForeachVar3()
        => VerifyTrue(AddInsideMethod(@"foreach(var ($$))"));

    [Fact]
    public void TestForeachVar4()
        => VerifyTrue(AddInsideMethod(@"foreach(var (x, $$"));

    [Fact]
    public void TestForeachVar5()
        => VerifyTrue(AddInsideMethod(@"foreach(var ($$) in "));

    [Fact]
    public void TestForeachVar6()
        => VerifyTrue(AddInsideMethod(@"foreach(var (($$), y)"));

    [Fact]
    public void TestForeachVar7()
        => VerifyTrue(AddInsideMethod(@"foreach(var (($$), y) in "));

    [Fact]
    public void TestForeachVar8()
        => VerifyTrue(AddInsideMethod(@"foreach(var ((x, $$), y)"));

    [Fact]
    public void TestForeachVar9()
        => VerifyTrue(AddInsideMethod(@"foreach(var ((x, $$), y) in "));

    [Fact]
    public void False1()
        => VerifyFalse(AddInsideMethod(@"var $$"));

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25084#issuecomment-369075537")]
    public void FalseAfterPattern1()
        => VerifyFalse(AddInsideMethod(@"if (1 is int i $$"));

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25084#issuecomment-369075537")]
    public void FalseAfterPattern2()
        => VerifyFalse(AddInsideMethod(@"if (1 is int i $$);"));

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25084#issuecomment-369075537")]
    public void FalseAfterPattern3()
        => VerifyFalse(AddInsideMethod(@"switch (1) { case int i $$ }"));
}
