// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.DotNet.OpenApi.Tests;
using Microsoft.Extensions.Tools.Internal;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.DotNet.OpenApi.Add.Tests;

public class OpenApiAddProjectTests : OpenApiTestBase
{
    public OpenApiAddProjectTests(ITestOutputHelper output) : base(output) { }

    [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")]
    public async Task OpenApi_Add_GlobbingOpenApi()
    {
        var project = CreateBasicProject(withOpenApi: true);

        using var refProj1 = project.Project.Dir().SubDir("refProj1");
        using var refProj2 = project.Project.Dir().SubDir("refProj2");
        var project1 = refProj1.WithCSharpProject("refProj");
        project1
            .WithTargetFrameworks(TestTFM)
            .Dir()
            .Create();

        var project2 = refProj2.WithCSharpProject("refProj2");
        project2
            .WithTargetFrameworks(TestTFM)
            .Dir()
            .Create();

        var app = GetApplication();

        var run = app.Execute(new[] { "add", "project", project1.Path, project2.Path });

        AssertNoErrors(run);

        // csproj contents
        using var csprojStream = new FileInfo(project.Project.Path).OpenRead();
        using var reader = new StreamReader(csprojStream);
        var content = await reader.ReadToEndAsync();
        Assert.Contains("<PackageReference Include=\"NSwag.ApiDescription.Client\" Version=\"", content);
        Assert.Contains($"<OpenApiProjectReference Include=\"{project1.Path}\"", content);
        Assert.Contains($"<OpenApiProjectReference Include=\"{project2.Path}\"", content);
    }

    [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")]
    public void OpenApi_Add_Project_EquivilentPaths()
    {
        var project = CreateBasicProject(withOpenApi: false);

        using var refProj = new TemporaryDirectory();
        var refProjName = "refProj";
        var csproj = refProj.WithCSharpProject(refProjName);
        csproj
            .WithTargetFrameworks(TestTFM)
            .Dir()
            .Create();

        var app = GetApplication();
        var run = app.Execute(new[] { "add", "project", csproj.Path });

        AssertNoErrors(run);

        app = GetApplication();
        run = app.Execute(new[] { "add", "project", Path.Combine(csproj.Path, "..", "refProj.csproj") });

        AssertNoErrors(run);

        var projXml = new XmlDocument();
        projXml.Load(project.Project.Path);

        var openApiRefs = projXml.GetElementsByTagName(Commands.BaseCommand.OpenApiProjectReference);
        Assert.Single(openApiRefs);
    }

    [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")]
    public async Task OpenApi_Add_FromCsProj()
    {
        var project = CreateBasicProject(withOpenApi: false);

        using var refProj = new TemporaryDirectory();
        var refProjName = "refProj";
        refProj
            .WithCSharpProject(refProjName)
            .WithTargetFrameworks(TestTFM)
            .Dir()
            .Create();

        var app = GetApplication();
        var refProjFile = Path.Join(refProj.Root, $"{refProjName}.csproj");
        var run = app.Execute(new[] { "add", "project", refProjFile });

        AssertNoErrors(run);

        // csproj contents
        using var csprojStream = new FileInfo(project.Project.Path).OpenRead();
        using var reader = new StreamReader(csprojStream);
        var content = await reader.ReadToEndAsync();
        Assert.Contains("<PackageReference Include=\"NSwag.ApiDescription.Client\" Version=\"", content);
        Assert.Contains($"<OpenApiProjectReference Include=\"{refProjFile}\"", content);
    }
}
