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

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils;

namespace Roslyn.VisualStudio.IntegrationTests.VisualBasic
{
    [Collection(nameof(SharedIntegrationHostFixture))]
    [Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)]
    public class BasicExtractInterfaceDialog : AbstractEditorTest
    {
        protected override string LanguageName => LanguageNames.VisualBasic;

        private ExtractInterfaceDialog_OutOfProc ExtractInterfaceDialog => VisualStudio.ExtractInterfaceDialog;

        public BasicExtractInterfaceDialog(VisualStudioInstanceFactory instanceFactory)
            : base(instanceFactory, nameof(BasicExtractInterfaceDialog))
        {
        }

        [WpfFact]
        public void CoreScenario()
        {
            SetUpEditor(@"Class C$$
    Public Sub M()
    End Sub
End Class");

            VisualStudio.Editor.InvokeCodeActionList();
            VisualStudio.Editor.Verify.CodeAction("Extract interface...",
                applyFix: true,
                blockUntilComplete: false);

            ExtractInterfaceDialog.VerifyOpen();
            ExtractInterfaceDialog.ClickOK();
            ExtractInterfaceDialog.VerifyClosed();

            var project = new ProjectUtils.Project(ProjectName);
            VisualStudio.SolutionExplorer.OpenFile(project, "Class1.vb");

            VisualStudio.Editor.Verify.TextContains(@"Class C
    Implements IC

    Public Sub M() Implements IC.M
    End Sub
End Class");

            VisualStudio.SolutionExplorer.OpenFile(project, "IC.vb");

            VisualStudio.Editor.Verify.TextContains(@"Interface IC
    Sub M()
End Interface");
        }

        [WpfFact]
        public void CheckFileName()
        {
            SetUpEditor(@"Class C2$$
    Public Sub M()
    End Sub
End Class");

            VisualStudio.Editor.InvokeCodeActionList();
            VisualStudio.Editor.Verify.CodeAction("Extract interface...",
                applyFix: true,
                blockUntilComplete: false);

            ExtractInterfaceDialog.VerifyOpen();

            var fileName = ExtractInterfaceDialog.GetTargetFileName();

            Assert.Equal(expected: "IC2.vb", actual: fileName);

            ExtractInterfaceDialog.ClickCancel();
        }

        [WpfFact]
        public void CheckSameFile()
        {
            SetUpEditor(@"Class C$$
    Public Sub M()
    End Sub
End Class");
            VisualStudio.Editor.InvokeCodeActionList();
            VisualStudio.Editor.Verify.CodeAction("Extract interface...",
                applyFix: true,
                blockUntilComplete: false);

            ExtractInterfaceDialog.VerifyOpen();

            ExtractInterfaceDialog.SelectSameFile();

            ExtractInterfaceDialog.ClickOK();
            ExtractInterfaceDialog.VerifyClosed();

            _ = new ProjectUtils.Project(ProjectName);
            VisualStudio.Editor.Verify.TextContains(@"Interface IC
    Sub M()
End Interface

Class C
    Implements IC

    Public Sub M() Implements IC.M
    End Sub
End Class");

        }

        [WpfFact]
        public void CheckSameFileOnlySelectedItems()
        {
            SetUpEditor(@"Class C$$
    Public Sub M1()
    Public Sub M2()
    End Sub
End Class");

            VisualStudio.Editor.InvokeCodeActionList();
            VisualStudio.Editor.Verify.CodeAction("Extract interface...",
                applyFix: true,
                blockUntilComplete: false);

            ExtractInterfaceDialog.VerifyOpen();
            ExtractInterfaceDialog.ClickDeselectAll();
            ExtractInterfaceDialog.ToggleItem("M2()");
            ExtractInterfaceDialog.SelectSameFile();
            ExtractInterfaceDialog.ClickOK();
            ExtractInterfaceDialog.VerifyClosed();

            VisualStudio.Editor.Verify.TextContains(@"Interface IC
    Sub M2()
End Interface

Class C
    Implements IC

    Public Sub M1()
    Public Sub M2() Implements IC.M2
    End Sub
End Class");
        }

        [WpfFact]
        public void CheckSameFileNamespace()
        {
            SetUpEditor(@"Namespace A
    Class C$$
        Public Sub M()
        End Sub
    End Class
End Namespace");

            VisualStudio.Editor.InvokeCodeActionList();
            VisualStudio.Editor.Verify.CodeAction("Extract interface...",
                applyFix: true,
                blockUntilComplete: false);

            ExtractInterfaceDialog.VerifyOpen();

            ExtractInterfaceDialog.SelectSameFile();

            ExtractInterfaceDialog.ClickOK();
            ExtractInterfaceDialog.VerifyClosed();

            _ = new ProjectUtils.Project(ProjectName);
            VisualStudio.Editor.Verify.TextContains(@"Namespace A
    Interface IC
        Sub M()
    End Interface

    Class C
        Implements IC

        Public Sub M() Implements IC.M
        End Sub
    End Class
End Namespace");
        }
    }
}
