using Nuke.Common;
using Nuke.Common.Git;
using Nuke.Common.IO;
using Nuke.Common.Tools.Docker;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.SonarScanner;
using Serilog;

sealed class Build : NukeBuild
{
    /// Support plugins are available for:
    ///   - JetBrains ReSharper        https://nuke.build/resharper
    ///   - JetBrains Rider            https://nuke.build/rider
    ///   - Microsoft VisualStudio     https://nuke.build/visualstudio
    ///   - Microsoft VSCode           https://nuke.build/vscode
    public static int Main() => Execute<Build>(x => x.Information, x => x.Deploy);

    [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
    readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;

    [Parameter] readonly bool SupportsDocker = true;

    [Parameter] readonly string SonarToken;
    [Parameter] readonly string SonarHostUrl;

    [Parameter] readonly string SonarProjectKey;

    GitRepository GitRepository => GitRepository.FromLocalDirectory(RootDirectory);

    Target Information => _ => _
        .Before(Clean)
        .Executes(() =>
        {
            Log.Information("Branch Name: {BranchName}", GitRepository.Branch);
            Log.Information("Commit: {Commit}", GitRepository.Commit);
        });

    Target Clean => _ => _
        .Before(Restore)
        .Executes(() => DotNetTasks.DotNetClean());

    Target Restore => _ => _
        .Executes(() => DotNetTasks.DotNetRestore());

    Target Compile => _ => _
        .DependsOn(Clean)
        .DependsOn(Restore)
        .Executes(() =>
        {
            if (IsLocalBuild && SupportsDocker)
            {
                DockerTasks.DockerStackRm(settings => settings.SetStacks("continuity"));
            }

            DotNetTasks.DotNetBuild(settings => settings.SetNoRestore(true));
        });

    Target Pack => _ => _
        .DependsOn(SonarScan)
        .Executes(() =>
        {
            if (!SupportsDocker)
            {
                return;
            }

            DockerTasks.DockerBuild(settings => settings
                .SetPath(AbsolutePath.Create(RootDirectory))
                .SetFile("Server/Dockerfile")
                .SetTag("continuity-server:latest")
                .SetCompress(true)
                .SetProgress(ProgressType.auto));
            if (!IsLocalBuild)
            {
                //DockerTasks.DockerPush(settings => settings.SetName("continuity-server:latest"));
            }
        });

    Target SonarScan => _ => _.DependsOn(Compile).Executes(() =>
    {
        if (IsLocalBuild)
        {
            return;
        }


        var sonarScannerSettings = new SonarScannerBeginSettings()
            .SetLogin(SonarToken)
            .SetProjectKey(SonarProjectKey)
            .SetServer(SonarHostUrl);
        SonarScannerTasks.SonarScannerBegin(sonarScannerSettings);
    });

    Target Deploy => _ => _.DependsOn(Pack).Executes(() =>
    {
        if (!SupportsDocker)
        {
            return;
        }

        DockerTasks.DockerPull(settings => settings.SetName("postgres:16.0-alpine"));
        if (IsLocalBuild)
        {
            var dockerComposeFile = AbsolutePath.Create(RootDirectory / "Server" / "docker-compose.yml");
            DockerTasks.DockerStackDeploy(settings => settings
                .AddComposeFile(dockerComposeFile)
                .SetStack("continuity")
                .SetPrune(true)
            );
            return;
        }

        Log.Error("Deploy is only available on local builds.");
    });
}