// Copyright 2023-2024 Gentoo Authors
// Distributed under the terms of the GNU General Public License v2

open System
open System.IO
open System.Threading.Tasks

open SimpleLog.SimpleLog
open System.CommandLine
open System.CommandLine.Invocation

open Gdmt.Checkcore.Private

let CommandName = "gdmt-checkcore"
let CommandDescription = "check versions of NuGet pkgs bound to SDK version"

let SdkMinVersionOption =
    new Option<string>([| "-m"; "--sdk-min" |], "minimal SDK version")

SdkMinVersionOption.SetDefaultValue "6.0"

let SdkMaxVersionOption =
    new Option<string>([| "-e"; "--sdk-ver" |], "targeted SDK version")

SdkMaxVersionOption.SetDefaultValue "8.0"

let SdkExecutableOption =
    new Option<string>([| "-x"; "--sdk-exe" |], "SDK executable path")

let CommandHandler (context: InvocationContext) : Task =
    task {
        let options = context.ParseResult

        let sdkMinVersion = double (options.GetValueForOption SdkMinVersionOption)
        let sdkMaxVersion = double (options.GetValueForOption SdkMaxVersionOption)

        let tempGuid = Guid.NewGuid().ToString()
        let tempName = $"gdmt_check_core_{tempGuid}"
        let tempPath = Path.Combine(Path.GetTempPath(), tempName)

        LogMessage Debug $"Temp path is: {tempPath}"

        for sdkVersion in GetSdkVersionChain sdkMinVersion sdkMaxVersion do
            let sdkVersionString = sprintf "%.1f" sdkVersion
            let sdkVersionTempPath = Path.Combine(tempPath, sdkVersionString)

            LogMessage Debug $"Starting restore for .NET {sdkVersionString}"

            Directory.CreateDirectory sdkVersionTempPath |> ignore
            WriteTempCsproj sdkVersionTempPath sdkVersionString

            let gdmtRestoreArgs =
                [ "-p"; sdkVersionTempPath ]
                @ match options.GetValueForOption SdkExecutableOption with
                  | empty when String.IsNullOrEmpty empty -> []
                  | s -> [ "--sdk-exe"; s ]

            RunGdmtRestore gdmtRestoreArgs
            Directory.Delete(sdkVersionTempPath, true)

        Directory.Delete(tempPath, true)

        ()
    }

[<EntryPoint>]
let main argv =
    let rootCommand = RootCommand(CommandName)

    rootCommand.Name <- CommandName
    rootCommand.Description <- CommandDescription

    rootCommand.AddOption SdkMinVersionOption
    rootCommand.AddOption SdkMaxVersionOption
    rootCommand.AddOption SdkExecutableOption

    rootCommand.SetHandler CommandHandler

    rootCommand.Invoke(argv)
