using Flo.Installer.Commands;

if (args.Length == 0 || args[0] is "--help" or "-h")
{
    PrintUsage();
    return 0;
}

try
{
    return args[0] switch
    {
        "install"   => await InstallCommand.ExecuteAsync(Required(args, "--manifest"), Required(args, "--install")),
        "provision" => await ProvisionCommand.ExecuteAsync(Required(args, "--install")),
        "setup"     => await Setup(args),
        "run"       => await RunCommand.ExecuteAsync(Required(args, "--install")),
        var cmd     => Unknown(cmd)
    };
}
catch (Exception ex)
{
    Console.Error.WriteLine($"Fatal: {ex.Message}");
    return 1;
}

static async Task<int> Setup(string[] args)
{
    string manifest = Required(args, "--manifest");
    string install  = Required(args, "--install");
    int rc = await InstallCommand.ExecuteAsync(manifest, install);
    if (rc != 0) return rc;
    return await ProvisionCommand.ExecuteAsync(install);
}

static int Unknown(string cmd)
{
    Console.Error.WriteLine($"Unknown command: {cmd}");
    PrintUsage();
    return 1;
}

static string Required(string[] args, string name)
{
    int i = Array.IndexOf(args, name);
    if (i < 0 || i + 1 >= args.Length)
        throw new ArgumentException($"{name} <value> is required.");
    return args[i + 1];
}

static void PrintUsage()
{
    Console.WriteLine("Flo Installer");
    Console.WriteLine();
    Console.WriteLine("Commands:");
    Console.WriteLine("  setup      --manifest <url> --install <path>   download + extract + provision DBs");
    Console.WriteLine("  install    --manifest <url> --install <path>   download + extract only");
    Console.WriteLine("  provision  --install <path>                    provision Postgres + FerretDB (idempotent)");
    Console.WriteLine("  run        --install <path>                    start Postgres + FerretDB, block on Ctrl-C");
}
