kxfides 0.1.0

CLI for signing & verifying media with KX-Fides.
// cli/src/main.rs

use anyhow::Result;
use clap::{Args, Parser, Subcommand};
use std::path::PathBuf;

// --- declare command modules (create these files in cli/src/) ---
mod cmd_hash;
mod cmd_keygen;
mod cmd_manifest_show;
mod cmd_sign;
mod cmd_verify;
// (optional shared helpers)
// mod util;

/// KX-Fides CLI — sign and verify media with authenticated manifests.
#[derive(Parser, Debug)]
#[command(name = "kx_fides_cli", version, about)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand, Debug)]
enum Commands {
    /// Generate an Ed25519 keypair (identity)
    Keygen(KeygenArgs),

    /// Compute the hash of a media file (debug/utility)
    Hash(HashArgs),

    /// Sign a media file, producing a detached .authmanifest.json
    Sign(SignArgs),

    /// Verify a media file against a manifest
    Verify(VerifyArgs),

    /// Manifest tools
    Manifest(ManifestCmd),
}

#[derive(Args, Debug)]
struct KeygenArgs {
    /// Output path for keypair JSON (e.g., mykey.json)
    #[arg(long, value_name = "FILE")]
    out: PathBuf,
}

#[derive(Args, Debug)]
struct HashArgs {
    /// Path to media file to hash
    #[arg(value_name = "MEDIA")]
    media: PathBuf,
}

#[derive(Args, Debug)]
struct SignArgs {
    /// Path to media file to sign
    #[arg(value_name = "MEDIA")]
    media: PathBuf,

    /// Path to keypair JSON generated by `keygen`
    #[arg(long, value_name = "KEY_JSON")]
    key: PathBuf,

    /// Output manifest path (e.g., media.authmanifest.json)
    #[arg(long, value_name = "MANIFEST_JSON")]
    out: PathBuf,

    /// Optional MIME type (e.g., audio/wav, image/jpeg)
    #[arg(long)]
    mime: Option<String>,
}

#[derive(Args, Debug)]
struct VerifyArgs {
    /// Path to media file to verify
    #[arg(value_name = "MEDIA")]
    media: PathBuf,

    /// Path to manifest JSON produced by `sign`
    #[arg(value_name = "MANIFEST_JSON")]
    manifest: PathBuf,
}

#[derive(Subcommand, Debug)]
enum ManifestSub {
    /// Pretty-print and validate a manifest JSON
    Show(ManifestShowArgs),
}

#[derive(Args, Debug)]
struct ManifestShowArgs {
    /// Path to manifest JSON
    #[arg(value_name = "MANIFEST_JSON")]
    manifest: PathBuf,
}

#[derive(Args, Debug)]
struct ManifestCmd {
    #[command(subcommand)]
    action: ManifestSub,
}

fn main() -> Result<()> {
    let cli = Cli::parse();

    match cli.command {
        Commands::Keygen(args) => cmd_keygen::run(args),
        Commands::Hash(args) => cmd_hash::run(args),
        Commands::Sign(args) => cmd_sign::run(args),
        Commands::Verify(args) => cmd_verify::run(args),
        Commands::Manifest(cmd) => match cmd.action {
            ManifestSub::Show(args) => cmd_manifest_show::run(args),
        },
    }
}