using System.CommandLine;
using {{ namespace }}.Cli;

var rootCommand = new RootCommand("{{ display_name }} MCP server");

var hostOption = new Option<string?>("--host");
var portOption = new Option<int?>("--port");
var corsAllowOption = new Option<string?>("--cors-allow");

var startCommand = new Command("start", "Start the Harness Server over stdio (for agent hosts).");
startCommand.SetAction((_, cancellationToken) => Roles.RunStdioHarnessAsync(args, cancellationToken));
rootCommand.Subcommands.Add(startCommand);

var httpCommand = new Command("http", "Start the Harness Server over HTTP (for agent hosts).")
{
    hostOption,
    portOption,
    corsAllowOption,
};
httpCommand.SetAction((parseResult, cancellationToken) => Roles.RunHttpHarnessAsync(
    args,
    parseResult.GetValue(hostOption),
    parseResult.GetValue(portOption),
    parseResult.GetValue(corsAllowOption),
    cancellationToken));
rootCommand.Subcommands.Add(httpCommand);

var versionCommand = new Command("version", "Print the installed version.");
versionCommand.SetAction(_ =>
{
    Roles.PrintVersion();
    return Task.FromResult(0);
});
rootCommand.Subcommands.Add(versionCommand);

var configCommand = new Command("config", "Print the resolved configuration (secrets redacted).");
configCommand.SetAction(async (_, cancellationToken) =>
{
    await Roles.PrintConfigAsync(args, cancellationToken);
    return 0;
});
rootCommand.Subcommands.Add(configCommand);

var versionsCommand = new Command("versions", "List the API spec versions available in this project.");
versionsCommand.SetAction(async (_, cancellationToken) =>
{
    await Roles.PrintVersionsAsync(args, cancellationToken);
    return 0;
});
rootCommand.Subcommands.Add(versionsCommand);

var queryArgument = new Argument<string>("query");
var limitOption = new Option<int>("--limit") { DefaultValueFactory = _ => 5 };
limitOption.Aliases.Add("-l");
var searchCommand = new Command("search", "Semantic search for operations matching a natural-language query.")
{
    queryArgument,
    limitOption,
};
searchCommand.SetAction((parseResult, _) => Roles.RunSearchAsync(
    args, parseResult.GetValue(queryArgument)!, parseResult.GetValue(limitOption)));
rootCommand.Subcommands.Add(searchCommand);

var getOperationIdArgument = new Argument<string>("operationId");
var getCommand = new Command("get", "Show the schema, path, method, and documentation for one operation.")
{
    getOperationIdArgument,
};
getCommand.SetAction(parseResult => Roles.RunGet(args, parseResult.GetValue(getOperationIdArgument)!));
rootCommand.Subcommands.Add(getCommand);

var callOperationIdArgument = new Argument<string>("operationId");
var callArgsOption = new Option<string>("--args") { DefaultValueFactory = _ => "{}" };
callArgsOption.Aliases.Add("-a");
var callCommand = new Command("call", "Validate arguments, invoke the live API, and validate the response.")
{
    callOperationIdArgument,
    callArgsOption,
};
callCommand.SetAction((parseResult, _) => Roles.RunCallAsync(
    args, parseResult.GetValue(callOperationIdArgument)!, parseResult.GetValue(callArgsOption)!));
rootCommand.Subcommands.Add(callCommand);

var populateAllOption = new Option<bool>("--all");
var populateApiVersionArgument = new Argument<string?>("apiVersion") { DefaultValueFactory = _ => null };
var populateEmbeddingsCommand = new Command(
    "populate-embeddings", "Backfill a store db's semantic_endpoints table.")
{
    populateAllOption,
    populateApiVersionArgument,
};
populateEmbeddingsCommand.SetAction((parseResult, cancellationToken) => Roles.RunPopulateEmbeddingsAsync(
    args,
    parseResult.GetValue(populateAllOption),
    parseResult.GetValue(populateApiVersionArgument),
    cancellationToken));
rootCommand.Subcommands.Add(populateEmbeddingsCommand);

var setupCommand = new Command(
    "setup", "Interactively configure {{ display_name }} credentials and connection settings.");
setupCommand.SetAction((_, _) => Roles.RunSetupAsync(args));
rootCommand.Subcommands.Add(setupCommand);

var testConnectionCommand = new Command(
    "test-connection", "Verify the configured API URL and credentials are reachable.");
testConnectionCommand.SetAction((_, _) => Roles.RunTestConnectionAsync(args));
rootCommand.Subcommands.Add(testConnectionCommand);

return await rootCommand.Parse(args).InvokeAsync();
