using System.CommandLine;
using System.CommandLine.Parsing;
using System.Text.Json;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// CLI adapters for the shared JSON schema library management contracts.
public static class SharedSchemaCommands
{
/// Builds the shared-schema list/get/create/update/delete command group.
/// Management URL option.
/// Output format option.
/// Authentication username option.
/// Authentication password option.
/// The configured shared-schema group.
public static Command Build(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption)
{
var group = new Command("shared-schema") { Description = "Manage the shared JSON schema library" };
var list = new Command("list") { Description = "List shared schemas" };
list.SetAction((ParseResult result) => Send(result, new ListSharedSchemasCommand()));
group.Add(list);
group.Add(BuildIdentity("get", id => new GetSharedSchemaCommand(id)));
group.Add(BuildEdit(update: false));
group.Add(BuildEdit(update: true));
group.Add(BuildIdentity("delete", id => new DeleteSharedSchemaCommand(id)));
return group;
Task Send(ParseResult result, object command) => CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption, command);
Command BuildIdentity(string verb, Func makeCommand)
{
var id = new Option("--id") { Description = "Shared schema ID", Required = true };
var command = new Command(verb) { Description = $"{(verb == "get" ? "Get" : "Delete")} a shared schema by ID" };
command.Add(id);
command.SetAction((ParseResult result) => Send(result, makeCommand(result.GetValue(id))));
return command;
}
Command BuildEdit(bool update)
{
var id = new Option("--id") { Description = "Shared schema ID", Required = true };
var name = new Option("--name") { Description = "Schema library name", Required = true };
var scope = new Option("--scope") { Description = "Optional schema scope; omission clears scope on update" };
var file = new Option("--schema-file") { Description = "Path to the JSON schema document", Required = true };
var command = new Command(update ? "update" : "create")
{
Description = update ? "Replace a shared schema's name, scope, and JSON document" : "Create a shared schema from a JSON file"
};
if (update) command.Add(id);
command.Add(name); command.Add(scope); command.Add(file);
command.SetAction(async (ParseResult result) =>
{
string json;
try
{
json = await File.ReadAllTextAsync(result.GetValue(file)!);
using var parsed = JsonDocument.Parse(json);
}
catch (JsonException ex)
{
OutputFormatter.WriteError($"Invalid schema JSON: {ex.Message}", "INVALID_JSON");
return 1;
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or ArgumentException)
{
OutputFormatter.WriteError($"Could not read schema file: {ex.Message}", "FILE_ERROR");
return 1;
}
// Structural schema validation, uniqueness, and authorization remain server-owned.
object request = update
? new UpdateSharedSchemaCommand(result.GetValue(id), result.GetValue(name)!, result.GetValue(scope), json)
: new CreateSharedSchemaCommand(result.GetValue(name)!, result.GetValue(scope), json);
return await Send(result, request);
});
return command;
}
}
}