use tracing::{info, error};
use apt_ostree::lib::error::AptOstreeError;
use apt_ostree::lib::logging::{LoggingManager, LoggingConfig, LogFormat, LogOutput};
use std::process;
use clap::Parser;
use crate::commands::Command;


mod commands;
mod cli;

#[tokio::main]
async fn main() {
    // Initialize enhanced logging system
    let logging_config = LoggingConfig {
        level: std::env::var("APT_OSTREE_LOG_LEVEL").unwrap_or_else(|_| "info".to_string()),
        format: if std::env::var("APT_OSTREE_LOG_FORMAT").unwrap_or_else(|_| "text".to_string()) == "json" {
            LogFormat::Json
        } else {
            LogFormat::Text
        },
        output: LogOutput::Console,
        file_path: std::env::var("APT_OSTREE_LOG_FILE").ok(),
        max_file_size: Some(100 * 1024 * 1024), // 100MB
        max_files: Some(7), // 7 days
        enable_metrics: true,
        enable_health_checks: true,
    };

    let logging_manager = LoggingManager::new(logging_config);
    if let Err(e) = logging_manager.init() {
        eprintln!("Failed to initialize logging system: {}", e);
        // Fallback to basic logging
        tracing_subscriber::fmt::init();
    }
    
    info!("apt-ostree starting with enhanced logging...");
    
    // Parse command line arguments with clap
    let cli = cli::Cli::parse();
    
    // Execute the command
    let result = match cli.command {
        cli::Commands::Status(_args) => {
            let mut args_vec = Vec::new();
            if _args.verbose { args_vec.push("--verbose".to_string()); }
            if _args.advisories { args_vec.push("--advisories".to_string()); }
            if _args.json { args_vec.push("--json".to_string()); }
            if let Some(ref jsonpath) = _args.jsonpath { args_vec.push(format!("--jsonpath={}", jsonpath)); }
            if _args.booted { args_vec.push("--booted".to_string()); }
            if _args.pending_exit_77 { args_vec.push("--pending-exit-77".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::system::StatusCommand::new().execute(&args_vec)
        },
        cli::Commands::Upgrade(_args) => {
            let mut args_vec = Vec::new();
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.preview { args_vec.push("--preview".to_string()); }
            if _args.check { args_vec.push("--check".to_string()); }
            if _args.cache_only { args_vec.push("--cache-only".to_string()); }
            if _args.download_only { args_vec.push("--download-only".to_string()); }
            if _args.unchanged_exit_77 { args_vec.push("--unchanged-exit-77".to_string()); }
            for pkg in &_args.install { args_vec.push(format!("--install={}", pkg)); }
            for pkg in &_args.uninstall { args_vec.push(format!("--uninstall={}", pkg)); }
            if _args.install.len() > 0 {
                for pkg in &_args.install {
                    args_vec.push(format!("--install={}", pkg));
                }
            }
            if _args.uninstall.len() > 0 {
                for pkg in &_args.uninstall {
                    args_vec.push(format!("--uninstall={}", pkg));
                }
            }
            commands::system::UpgradeCommand::new().execute(&args_vec)
        },
        cli::Commands::Rollback(_args) => {
            let mut args_vec = Vec::new();
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::system::RollbackCommand::new().execute(&args_vec)
        },
        cli::Commands::Deploy(_args) => {
            let mut args_vec = vec![_args.commit];
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.preview { args_vec.push("--preview".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if _args.cache_only { args_vec.push("--cache-only".to_string()); }
            if _args.download_only { args_vec.push("--download-only".to_string()); }
            if let Some(ref install) = _args.install { args_vec.push(format!("--install={}", install)); }
            if let Some(ref uninstall) = _args.uninstall { args_vec.push(format!("--uninstall={}", uninstall)); }
            commands::system::DeployCommand::new().execute(&args_vec)
        },
        cli::Commands::Rebase(_args) => {
            let mut args_vec = vec![_args.target];
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.skip_purge { args_vec.push("--skip-purge".to_string()); }
            if let Some(ref branch) = _args.branch { args_vec.push(format!("--branch={}", branch)); }
            if let Some(ref remote) = _args.remote { args_vec.push(format!("--remote={}", remote)); }
            if _args.cache_only { args_vec.push("--cache-only".to_string()); }
            if _args.download_only { args_vec.push("--download-only".to_string()); }
            if let Some(ref custom_origin_description) = _args.custom_origin_description { args_vec.push(format!("--custom-origin-description={}", custom_origin_description)); }
            if let Some(ref custom_origin_url) = _args.custom_origin_url { args_vec.push(format!("--custom-origin-url={}", custom_origin_url)); }
            if _args.experimental { args_vec.push("--experimental".to_string()); }
            if _args.disallow_downgrade { args_vec.push("--disallow-downgrade".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if _args.bypass_driver { args_vec.push("--bypass-driver".to_string()); }
            if let Some(ref install) = _args.install { args_vec.push(format!("--install={}", install)); }
            if let Some(ref uninstall) = _args.uninstall { args_vec.push(format!("--uninstall={}", uninstall)); }
            commands::system::RebaseCommand::new().execute(&args_vec)
        },
        cli::Commands::Install(_args) => {
            let mut args_vec = _args.packages;
            if _args.dry_run { args_vec.push("--dry-run".to_string()); }
            if _args.cache_only { args_vec.push("--cache-only".to_string()); }
            if _args.download_only { args_vec.push("--download-only".to_string()); }
            if _args.apply_live { args_vec.push("--apply-live".to_string()); }
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if _args.idempotent { args_vec.push("--idempotent".to_string()); }
            commands::packages::InstallCommand::new().execute(&args_vec)
        },
        cli::Commands::Uninstall(_args) => {
            let mut args_vec = _args.packages;
            if _args.all { args_vec.push("--all".to_string()); }
            if _args.dry_run { args_vec.push("--dry-run".to_string()); }
            if _args.cache_only { args_vec.push("--cache-only".to_string()); }
            if _args.download_only { args_vec.push("--download-only".to_string()); }
            if _args.apply_live { args_vec.push("--apply-live".to_string()); }
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            commands::packages::UninstallCommand::new().execute(&args_vec)
        },
        cli::Commands::Search(_args) => {
            let mut args_vec = vec![_args.query];
            if let Some(ref pkg) = _args.uninstall { args_vec.push(format!("--uninstall={}", pkg)); }
            if _args.cache_only { args_vec.push("--cache-only".to_string()); }
            if _args.download_only { args_vec.push("--download-only".to_string()); }
            if _args.apply_live { args_vec.push("--apply-live".to_string()); }
            if _args.force_replacefiles { args_vec.push("--force-replacefiles".to_string()); }
            if let Some(ref pkg) = _args.install { args_vec.push(format!("--install={}", pkg)); }
            if _args.all { args_vec.push("--all".to_string()); }
            if let Some(ref stateroot) = _args.stateroot { args_vec.push(format!("--stateroot={}", stateroot)); }
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.dry_run { args_vec.push("--dry-run".to_string()); }
            if _args.assumeyes { args_vec.push("--assumeyes".to_string()); }
            if _args.allow_inactive { args_vec.push("--allow-inactive".to_string()); }
            if _args.idempotent { args_vec.push("--idempotent".to_string()); }
            if _args.unchanged_exit_77 { args_vec.push("--unchanged-exit-77".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if let Some(ref repo) = _args.enablerepo { args_vec.push(format!("--enablerepo={}", repo)); }
            if let Some(ref repo) = _args.disablerepo { args_vec.push(format!("--disablerepo={}", repo)); }
            if let Some(ref ver) = _args.releasever { args_vec.push(format!("--releasever={}", ver)); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::packages::SearchCommand::new().execute(&args_vec)
        },
        cli::Commands::Initramfs(_args) => {
            let mut args_vec = Vec::new();
            if _args.enable { args_vec.push("--enable".to_string()); }
            if _args.disable { args_vec.push("--disable".to_string()); }
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if let Some(ref arg) = _args.arg { args_vec.push(format!("--arg={}", arg)); }
            commands::system::InitramfsCommand::new().execute(&args_vec)
        },
        cli::Commands::InitramfsEtc(_args) => {
            let mut args_vec = Vec::new();
            if _args.force_sync { args_vec.push("--force-sync".to_string()); }
            if let Some(ref file) = _args.track { args_vec.push(format!("--track={}", file)); }
            if let Some(ref file) = _args.untrack { args_vec.push(format!("--untrack={}", file)); }
            if _args.untrack_all { args_vec.push("--untrack-all".to_string()); }
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if _args.unchanged_exit_77 { args_vec.push("--unchanged-exit-77".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::system::InitramfsEtcCommand::new().execute(&args_vec)
        },
        cli::Commands::Kargs(_args) => {
            let mut args_vec = Vec::new();
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.lock_finalization { args_vec.push("--lock-finalization".to_string()); }
            if _args.unchanged_exit_77 { args_vec.push("--unchanged-exit-77".to_string()); }
            if _args.import_proc_cmdline { args_vec.push("--import-proc-cmdline".to_string()); }
            if _args.editor { args_vec.push("--editor".to_string()); }
            if let Some(idx) = _args.deploy_index { args_vec.push(format!("--deploy-index={}", idx)); }
            for arg in &_args.append { args_vec.push(format!("--append={}", arg)); }
            for arg in &_args.replace { args_vec.push(format!("--replace={}", arg)); }
            for arg in &_args.delete { args_vec.push(format!("--delete={}", arg)); }
            for arg in &_args.append_if_missing { args_vec.push(format!("--append-if-missing={}", arg)); }
            for arg in &_args.delete_if_present { args_vec.push(format!("--delete-if-present={}", arg)); }
            commands::system::KargsCommand::new().execute(&args_vec)
        },
        cli::Commands::Reload(_args) => {
            let mut args_vec = Vec::new();
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::system::ReloadCommand::new().execute(&args_vec)
        },
        cli::Commands::Cancel(_args) => {
            let mut args_vec = Vec::new();
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::system::CancelCommand::new().execute(&args_vec)
        },
        cli::Commands::Transaction(_args) => {
            let args_vec = vec!["transaction".to_string()];
            commands::transactions::TransactionCommand::new().execute(&args_vec)
        },
        cli::Commands::Compose(args) => {
            match &args.subcommand {
                cli::ComposeSubcommands::Tree { treefile, repo, layer_repo, force_nocache, cache_only, cachedir, source_root, download_only, download_only_rpms, proxy, dry_run, print_only, disable_selinux, touch_if_changed, previous_commit, previous_inputhash, previous_version, workdir, postprocess, ex_write_lockfile_to, ex_lockfile, ex_lockfile_strict, add_metadata_string, add_metadata_from_json, write_commitid_to, write_composejson_to, no_parent, parent, verbose, container } => {
                    let mut args_vec = vec!["tree".to_string(), treefile.clone()];
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    if let Some(ref lr) = layer_repo {
                        args_vec.extend_from_slice(&["--layer-repo".to_string(), lr.clone()]);
                    }
                    if *force_nocache {
                        args_vec.push("--force-nocache".to_string());
                    }
                    if *cache_only {
                        args_vec.push("--cache-only".to_string());
                    }
                    if let Some(ref cd) = cachedir {
                        args_vec.extend_from_slice(&["--cachedir".to_string(), cd.clone()]);
                    }
                    if let Some(ref sr) = source_root {
                        args_vec.extend_from_slice(&["--source-root".to_string(), sr.clone()]);
                    }
                    if *download_only {
                        args_vec.push("--download-only".to_string());
                    }
                    if *download_only_rpms {
                        args_vec.push("--download-only-rpms".to_string());
                    }
                    if let Some(ref p) = proxy {
                        args_vec.extend_from_slice(&["--proxy".to_string(), p.clone()]);
                    }
                    if *dry_run {
                        args_vec.push("--dry-run".to_string());
                    }
                    if *print_only {
                        args_vec.push("--print-only".to_string());
                    }
                    if *disable_selinux {
                        args_vec.push("--disable-selinux".to_string());
                    }
                    if let Some(ref tic) = touch_if_changed {
                        args_vec.extend_from_slice(&["--touch-if-changed".to_string(), tic.clone()]);
                    }
                    if let Some(ref pc) = previous_commit {
                        args_vec.extend_from_slice(&["--previous-commit".to_string(), pc.clone()]);
                    }
                    if let Some(ref pih) = previous_inputhash {
                        args_vec.extend_from_slice(&["--previous-inputhash".to_string(), pih.clone()]);
                    }
                    if let Some(ref pv) = previous_version {
                        args_vec.extend_from_slice(&["--previous-version".to_string(), pv.clone()]);
                    }
                    if let Some(ref wd) = workdir {
                        args_vec.extend_from_slice(&["--workdir".to_string(), wd.clone()]);
                    }
                    if *postprocess {
                        args_vec.push("--postprocess".to_string());
                    }
                    if let Some(ref ewlt) = ex_write_lockfile_to {
                        args_vec.extend_from_slice(&["--ex-write-lockfile-to".to_string(), ewlt.clone()]);
                    }
                    if let Some(ref el) = ex_lockfile {
                        args_vec.extend_from_slice(&["--ex-lockfile".to_string(), el.clone()]);
                    }
                    if *ex_lockfile_strict {
                        args_vec.push("--ex-lockfile-strict".to_string());
                    }
                    for ams in add_metadata_string {
                        args_vec.extend_from_slice(&["--add-metadata-string".to_string(), ams.clone()]);
                    }
                    if let Some(ref amfj) = add_metadata_from_json {
                        args_vec.extend_from_slice(&["--add-metadata-from-json".to_string(), amfj.clone()]);
                    }
                    if let Some(ref wct) = write_commitid_to {
                        args_vec.extend_from_slice(&["--write-commitid-to".to_string(), wct.clone()]);
                    }
                    if let Some(ref wcj) = write_composejson_to {
                        args_vec.extend_from_slice(&["--write-composejson-to".to_string(), wcj.clone()]);
                    }
                    if *no_parent {
                        args_vec.push("--no-parent".to_string());
                    }
                    if let Some(ref p) = parent {
                        args_vec.extend_from_slice(&["--parent".to_string(), p.clone()]);
                    }
                    if *verbose {
                        args_vec.push("--verbose".to_string());
                    }
                    if *container {
                        args_vec.push("--container".to_string());
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::Install { treefile, destdir, repo, layer_repo, force_nocache, cache_only, cachedir, source_root, download_only, download_only_rpms, proxy, dry_run, print_only, disable_selinux, touch_if_changed, previous_commit, previous_inputhash, previous_version, workdir, postprocess, ex_write_lockfile_to, ex_lockfile, ex_lockfile_strict } => {
                    let mut args_vec = vec!["install".to_string(), treefile.clone(), destdir.clone()];
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    if let Some(ref lr) = layer_repo {
                        args_vec.extend_from_slice(&["--layer-repo".to_string(), lr.clone()]);
                    }
                    if *force_nocache {
                        args_vec.push("--force-nocache".to_string());
                    }
                    if *cache_only {
                        args_vec.push("--cache-only".to_string());
                    }
                    if let Some(ref cd) = cachedir {
                        args_vec.extend_from_slice(&["--cachedir".to_string(), cd.clone()]);
                    }
                    if let Some(ref sr) = source_root {
                        args_vec.extend_from_slice(&["--source-root".to_string(), sr.clone()]);
                    }
                    if *download_only {
                        args_vec.push("--download-only".to_string());
                    }
                    if *download_only_rpms {
                        args_vec.push("--download-only-rpms".to_string());
                    }
                    if let Some(ref p) = proxy {
                        args_vec.extend_from_slice(&["--proxy".to_string(), p.clone()]);
                    }
                    if *dry_run {
                        args_vec.push("--dry-run".to_string());
                    }
                    if *print_only {
                        args_vec.push("--print-only".to_string());
                    }
                    if *disable_selinux {
                        args_vec.push("--disable-selinux".to_string());
                    }
                    if let Some(ref tic) = touch_if_changed {
                        args_vec.extend_from_slice(&["--touch-if-changed".to_string(), tic.clone()]);
                    }
                    if let Some(ref pc) = previous_commit {
                        args_vec.extend_from_slice(&["--previous-commit".to_string(), pc.clone()]);
                    }
                    if let Some(ref pih) = previous_inputhash {
                        args_vec.extend_from_slice(&["--previous-inputhash".to_string(), pih.clone()]);
                    }
                    if let Some(ref pv) = previous_version {
                        args_vec.extend_from_slice(&["--previous-version".to_string(), pv.clone()]);
                    }
                    if let Some(ref wd) = workdir {
                        args_vec.extend_from_slice(&["--workdir".to_string(), wd.clone()]);
                    }
                    if *postprocess {
                        args_vec.push("--postprocess".to_string());
                    }
                    if let Some(ref ewlt) = ex_write_lockfile_to {
                        args_vec.extend_from_slice(&["--ex-write-lockfile-to".to_string(), ewlt.clone()]);
                    }
                    if let Some(ref el) = ex_lockfile {
                        args_vec.extend_from_slice(&["--ex-lockfile".to_string(), el.clone()]);
                    }
                    if *ex_lockfile_strict {
                        args_vec.push("--ex-lockfile-strict".to_string());
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::Postprocess { rootfs, treefile } => {
                    let mut args_vec = vec!["postprocess".to_string(), rootfs.clone()];
                    if let Some(ref tf) = treefile {
                        args_vec.push(tf.clone());
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::Commit { treefile, rootfs, repo, layer_repo, unified_core, add_metadata_string, add_metadata_from_json, write_commitid_to, write_composejson_to, no_parent, parent } => {
                    let mut args_vec = vec!["commit".to_string(), treefile.clone(), rootfs.clone()];
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    if let Some(ref lr) = layer_repo {
                        args_vec.extend_from_slice(&["--layer-repo".to_string(), lr.clone()]);
                    }
                    if *unified_core {
                        args_vec.push("--unified-core".to_string());
                    }
                    for ams in add_metadata_string {
                        args_vec.extend_from_slice(&["--add-metadata-string".to_string(), ams.clone()]);
                    }
                    if let Some(ref amfj) = add_metadata_from_json {
                        args_vec.extend_from_slice(&["--add-metadata-from-json".to_string(), amfj.clone()]);
                    }
                    if let Some(ref wct) = write_commitid_to {
                        args_vec.extend_from_slice(&["--write-commitid-to".to_string(), wct.clone()]);
                    }
                    if let Some(ref wcj) = write_composejson_to {
                        args_vec.extend_from_slice(&["--write-composejson-to".to_string(), wcj.clone()]);
                    }
                    if *no_parent {
                        args_vec.push("--no-parent".to_string());
                    }
                    if let Some(ref p) = parent {
                        args_vec.extend_from_slice(&["--parent".to_string(), p.clone()]);
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::Extensions { treefile, extyaml, repo, layer_repo, unified_core, output_dir, base_rev, cachedir, rootfs, touch_if_changed } => {
                    let mut args_vec = vec!["extensions".to_string(), treefile.clone(), extyaml.clone()];
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    if let Some(ref lr) = layer_repo {
                        args_vec.extend_from_slice(&["--layer-repo".to_string(), lr.clone()]);
                    }
                    if *unified_core {
                        args_vec.push("--unified-core".to_string());
                    }
                    if let Some(ref od) = output_dir {
                        args_vec.extend_from_slice(&["--output-dir".to_string(), od.clone()]);
                    }
                    if let Some(ref br) = base_rev {
                        args_vec.extend_from_slice(&["--base-rev".to_string(), br.clone()]);
                    }
                    if let Some(ref cd) = cachedir {
                        args_vec.extend_from_slice(&["--cachedir".to_string(), cd.clone()]);
                    }
                    if let Some(ref r) = rootfs {
                        args_vec.extend_from_slice(&["--rootfs".to_string(), r.clone()]);
                    }
                    if let Some(ref tic) = touch_if_changed {
                        args_vec.extend_from_slice(&["--touch-if-changed".to_string(), tic.clone()]);
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::Image { manifest, output, cachedir, source_root, authfile, layer_repo, initialize, initialize_mode, format, force_nocache, offline, write_lockfile_to, lockfile, lockfile_strict, label, image_config, touch_if_changed, copy_retry_times, max_layers } => {
                    let mut args_vec = vec!["image".to_string(), manifest.clone(), output.clone()];
                    if let Some(ref cd) = cachedir {
                        args_vec.extend_from_slice(&["--cachedir".to_string(), cd.clone()]);
                    }
                    if let Some(ref sr) = source_root {
                        args_vec.extend_from_slice(&["--source-root".to_string(), sr.clone()]);
                    }
                    if let Some(ref af) = authfile {
                        args_vec.extend_from_slice(&["--authfile".to_string(), af.clone()]);
                    }
                    if let Some(ref lr) = layer_repo {
                        args_vec.extend_from_slice(&["--layer-repo".to_string(), lr.clone()]);
                    }
                    if *initialize {
                        args_vec.push("--initialize".to_string());
                    }
                    if let Some(ref im) = initialize_mode {
                        args_vec.extend_from_slice(&["--initialize-mode".to_string(), im.clone()]);
                    }
                    if let Some(ref f) = format {
                        args_vec.extend_from_slice(&["--format".to_string(), f.clone()]);
                    }
                    if *force_nocache {
                        args_vec.push("--force-nocache".to_string());
                    }
                    if *offline {
                        args_vec.push("--offline".to_string());
                    }
                    if let Some(ref wlt) = write_lockfile_to {
                        args_vec.extend_from_slice(&["--write-lockfile-to".to_string(), wlt.clone()]);
                    }
                    for lf in lockfile {
                        args_vec.extend_from_slice(&["--lockfile".to_string(), lf.clone()]);
                    }
                    if *lockfile_strict {
                        args_vec.push("--lockfile-strict".to_string());
                    }
                    for l in label {
                        args_vec.extend_from_slice(&["--label".to_string(), l.clone()]);
                    }
                    if let Some(ref ic) = image_config {
                        args_vec.extend_from_slice(&["--image-config".to_string(), ic.clone()]);
                    }
                    if let Some(ref tic) = touch_if_changed {
                        args_vec.extend_from_slice(&["--touch-if-changed".to_string(), tic.clone()]);
                    }
                    if let Some(ref crt) = copy_retry_times {
                        args_vec.extend_from_slice(&["--copy-retry-times".to_string(), crt.to_string()]);
                    }
                    if let Some(ref ml) = max_layers {
                        args_vec.extend_from_slice(&["--max-layers".to_string(), ml.to_string()]);
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::Rootfs { manifest, dest, cachedir, source_root, source_root_rw } => {
                    let mut args_vec = vec!["rootfs".to_string(), manifest.clone(), dest.clone()];
                    if let Some(ref cd) = cachedir {
                        args_vec.extend_from_slice(&["--cachedir".to_string(), cd.clone()]);
                    }
                    if let Some(ref sr) = source_root {
                        args_vec.extend_from_slice(&["--source-root".to_string(), sr.clone()]);
                    }
                    if let Some(ref srr) = source_root_rw {
                        args_vec.extend_from_slice(&["--source-root-rw".to_string(), srr.clone()]);
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::BuildChunkedOci { rootfs, from, bootc, format_version, max_layers, reference, output } => {
                    let mut args_vec = vec!["build-chunked-oci".to_string()];
                    if let Some(ref r) = rootfs {
                        args_vec.extend_from_slice(&["--rootfs".to_string(), r.clone()]);
                    }
                    if let Some(ref f) = from {
                        args_vec.extend_from_slice(&["--from".to_string(), f.clone()]);
                    }
                    if *bootc {
                        args_vec.push("--bootc".to_string());
                    }
                    if let Some(ref fv) = format_version {
                        args_vec.extend_from_slice(&["--format-version".to_string(), fv.clone()]);
                    }
                    if let Some(ref ml) = max_layers {
                        args_vec.extend_from_slice(&["--max-layers".to_string(), ml.to_string()]);
                    }
                    if let Some(ref r) = reference {
                        args_vec.extend_from_slice(&["--reference".to_string(), r.clone()]);
                    }
                    args_vec.extend_from_slice(&["--output".to_string(), output.clone()]);
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
                cli::ComposeSubcommands::ContainerEncapsulate { ostree_ref, imgref, repo, label, image_config, arch, copymeta, copymeta_opt, cmd, max_layers, format_version, write_contentmeta_json, compare_with_build, previous_build_manifest } => {
                    let mut args_vec = vec!["container-encapsulate".to_string(), ostree_ref.clone(), imgref.clone()];
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    for l in label {
                        args_vec.extend_from_slice(&["--label".to_string(), l.clone()]);
                    }
                    if let Some(ref ic) = image_config {
                        args_vec.extend_from_slice(&["--image-config".to_string(), ic.clone()]);
                    }
                    if let Some(ref a) = arch {
                        args_vec.extend_from_slice(&["--arch".to_string(), a.clone()]);
                    }
                    for cm in copymeta {
                        args_vec.extend_from_slice(&["--copymeta".to_string(), cm.clone()]);
                    }
                    for cmo in copymeta_opt {
                        args_vec.extend_from_slice(&["--copymeta-opt".to_string(), cmo.clone()]);
                    }
                    if let Some(ref c) = cmd {
                        args_vec.extend_from_slice(&["--cmd".to_string(), c.clone()]);
                    }
                    if let Some(ref ml) = max_layers {
                        args_vec.extend_from_slice(&["--max-layers".to_string(), ml.to_string()]);
                    }
                    if let Some(ref fv) = format_version {
                        args_vec.extend_from_slice(&["--format-version".to_string(), fv.clone()]);
                    }
                    if let Some(ref wcmj) = write_contentmeta_json {
                        args_vec.extend_from_slice(&["--write-contentmeta-json".to_string(), wcmj.clone()]);
                    }
                    if let Some(ref cwb) = compare_with_build {
                        args_vec.extend_from_slice(&["--compare-with-build".to_string(), cwb.clone()]);
                    }
                    if let Some(ref pbm) = previous_build_manifest {
                        args_vec.extend_from_slice(&["--previous-build-manifest".to_string(), pbm.clone()]);
                    }
                    commands::advanced::ComposeCommand::new().execute(&args_vec)
                },
            }
        },
        cli::Commands::Db(args) => {
            match &args.subcommand {
                cli::DbSubcommands::List => {
                    let args_vec = vec!["list".to_string()];
                    commands::advanced::DbCommand::new().execute(&args_vec)
                },
                cli::DbSubcommands::Info { package } => {
                    let args_vec = vec!["info".to_string(), package.clone()];
                    commands::advanced::DbCommand::new().execute(&args_vec)
                },
                cli::DbSubcommands::Search { query } => {
                    let args_vec = vec!["search".to_string(), query.clone()];
                    commands::advanced::DbCommand::new().execute(&args_vec)
                },
                cli::DbSubcommands::Depends { package } => {
                    let args_vec = vec!["depends".to_string(), package.clone()];
                    commands::advanced::DbCommand::new().execute(&args_vec)
                },
                cli::DbSubcommands::Install { packages, target, repo } => {
                    let mut args_vec = vec!["install".to_string()];
                    args_vec.extend(packages.iter().map(|p| p.clone()));
                    args_vec.extend_from_slice(&["--target".to_string(), target.clone()]);
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    commands::advanced::DbCommand::new().execute(&args_vec)
                },
                cli::DbSubcommands::Remove { packages, target, repo } => {
                    let mut args_vec = vec!["remove".to_string()];
                    args_vec.extend(packages.iter().map(|p| p.clone()));
                    args_vec.extend_from_slice(&["--target".to_string(), target.clone()]);
                    if let Some(ref r) = repo {
                        args_vec.extend_from_slice(&["--repo".to_string(), r.clone()]);
                    }
                    commands::advanced::DbCommand::new().execute(&args_vec)
                },
            }
        },
        cli::Commands::Override(args) => {
            match &args.subcommand {
                cli::OverrideSubcommands::Remove { packages, replace, stateroot, reboot, dry_run, lock_finalization, cache_only, sysroot, peer, install, uninstall, .. } => {
                    let mut args_vec = vec!["remove".to_string()];
                    args_vec.extend(packages.iter().map(|p| p.clone()));
                    if let Some(ref pkg) = replace { args_vec.push(format!("--replace={}", pkg)); }
                    if let Some(ref root) = stateroot { args_vec.push(format!("--stateroot={}", root)); }
                    if *reboot { args_vec.push("--reboot".to_string()); }
                    if *dry_run { args_vec.push("--dry-run".to_string()); }
                    if *lock_finalization { args_vec.push("--lock-finalization".to_string()); }
                    if *cache_only { args_vec.push("--cache-only".to_string()); }
                    if let Some(ref root) = sysroot { args_vec.push(format!("--sysroot={}", root)); }
                    if *peer { args_vec.push("--peer".to_string()); }
                    if let Some(ref pkg) = install { args_vec.push(format!("--install={}", pkg)); }
                    if let Some(ref pkg) = uninstall { args_vec.push(format!("--uninstall={}", pkg)); }
                    commands::advanced::OverrideCommand::new().execute(&args_vec)
                },
                cli::OverrideSubcommands::Replace { packages, remove, stateroot, reboot, dry_run, lock_finalization, cache_only, sysroot, peer, install, uninstall, .. } => {
                    let mut args_vec = vec!["replace".to_string()];
                    args_vec.extend(packages.iter().map(|p| p.clone()));
                    if let Some(ref pkg) = remove { args_vec.push(format!("--remove={}", pkg)); }
                    if let Some(ref root) = stateroot { args_vec.push(format!("--stateroot={}", root)); }
                    if *reboot { args_vec.push("--reboot".to_string()); }
                    if *dry_run { args_vec.push("--dry-run".to_string()); }
                    if *lock_finalization { args_vec.push("--lock-finalization".to_string()); }
                    if *cache_only { args_vec.push("--cache-only".to_string()); }
                    if let Some(ref root) = sysroot { args_vec.push(format!("--sysroot={}", root)); }
                    if *peer { args_vec.push("--peer".to_string()); }
                    if let Some(ref pkg) = install { args_vec.push(format!("--install={}", pkg)); }
                    if let Some(ref pkg) = uninstall { args_vec.push(format!("--uninstall={}", pkg)); }
                    commands::advanced::OverrideCommand::new().execute(&args_vec)
                },
                cli::OverrideSubcommands::Reset { all, stateroot, reboot, dry_run, lock_finalization, cache_only, sysroot, peer, install, uninstall, .. } => {
                    let mut args_vec = vec!["reset".to_string()];
                    if *all { args_vec.push("--all".to_string()); }
                    if let Some(ref root) = stateroot { args_vec.push(format!("--stateroot={}", root)); }
                    if *reboot { args_vec.push("--reboot".to_string()); }
                    if *dry_run { args_vec.push("--dry-run".to_string()); }
                    if *lock_finalization { args_vec.push("--lock-finalization".to_string()); }
                    if *cache_only { args_vec.push("--cache-only".to_string()); }
                    if let Some(ref root) = sysroot { args_vec.push(format!("--sysroot={}", root)); }
                    if *peer { args_vec.push("--peer".to_string()); }
                    if let Some(ref pkg) = install { args_vec.push(format!("--install={}", pkg)); }
                    if let Some(ref pkg) = uninstall { args_vec.push(format!("--uninstall={}", pkg)); }
                    commands::advanced::OverrideCommand::new().execute(&args_vec)
                },
            }
        },
        cli::Commands::Reset(_args) => {
            let mut args_vec = Vec::new();
            if let Some(ref stateroot) = _args.stateroot { args_vec.push(format!("--stateroot={}", stateroot)); }
            if _args.reboot { args_vec.push("--reboot".to_string()); }
            if _args.overlays { args_vec.push("--overlays".to_string()); }
            if _args.overrides { args_vec.push("--overrides".to_string()); }
            if _args.initramfs { args_vec.push("--initramfs".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            if let Some(ref pkg) = _args.install { args_vec.push(format!("--install={}", pkg)); }
            if let Some(ref pkg) = _args.uninstall { args_vec.push(format!("--uninstall={}", pkg)); }
            commands::advanced::ResetCommand::new().execute(&args_vec)
        },
        cli::Commands::RefreshMd(_args) => {
            let mut args_vec = Vec::new();
            if let Some(ref stateroot) = _args.stateroot { args_vec.push(format!("--stateroot={}", stateroot)); }
            if _args.force { args_vec.push("--force".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::advanced::RefreshMdCommand::new().execute(&args_vec)
        },
        cli::Commands::ApplyLive(_args) => {
            let mut args_vec = Vec::new();
            if let Some(ref target) = _args.target { args_vec.push(format!("--target={}", target)); }
            if _args.reset { args_vec.push("--reset".to_string()); }
            if _args.allow_replacement { args_vec.push("--allow-replacement".to_string()); }
            commands::live::ApplyLiveCommand::new().execute(&args_vec)
        },
        cli::Commands::Usroverlay(_args) => {
            let mut args_vec = Vec::new();
            if _args.hotfix { args_vec.push("--hotfix".to_string()); }
            if _args.transient { args_vec.push("--transient".to_string()); }
            if _args.verbose { args_vec.push("--verbose".to_string()); }
            commands::live::UsroverlayCommand::new().execute(&args_vec)
        },
        cli::Commands::Cleanup(_args) => {
            let mut args_vec = Vec::new();
            if let Some(ref stateroot) = _args.stateroot { args_vec.push(format!("--stateroot={}", stateroot)); }
            if _args.base { args_vec.push("--base".to_string()); }
            if _args.pending { args_vec.push("--pending".to_string()); }
            if _args.rollback { args_vec.push("--rollback".to_string()); }
            if _args.repomd { args_vec.push("--repomd".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::utils::CleanupCommand::new().execute(&args_vec)
        },
        cli::Commands::FinalizeDeployment(_args) => {
            let mut args_vec = Vec::new();
            args_vec.push(_args.checksum.clone());
            if let Some(ref stateroot) = _args.stateroot { args_vec.push(format!("--stateroot={}", stateroot)); }
            if _args.allow_missing_checksum { args_vec.push("--allow-missing-checksum".to_string()); }
            if _args.allow_unlocked { args_vec.push("--allow-unlocked".to_string()); }
            if let Some(ref sysroot) = _args.sysroot { args_vec.push(format!("--sysroot={}", sysroot)); }
            if _args.peer { args_vec.push("--peer".to_string()); }
            commands::utils::FinalizeDeploymentCommand::new().execute(&args_vec)
        },
        cli::Commands::Metrics(_args) => {
            let mut args_vec = Vec::new();
            if _args.system { args_vec.push("--system".to_string()); }
            if _args.performance { args_vec.push("--performance".to_string()); }
            if _args.all { args_vec.push("--all".to_string()); }
            commands::utils::MetricsCommand::new().execute(&args_vec)
        },
        cli::Commands::StartDaemon(_args) => {
            let mut args_vec = Vec::new();
            if _args.debug { args_vec.push("--debug".to_string()); }
            args_vec.push(format!("--sysroot={}", _args.sysroot));
            commands::system::StartDaemonCommand::new().execute(&args_vec)
        },
        cli::Commands::Ex(_args) => {
            let args_vec = vec!["ex".to_string()];
            commands::experimental::ExCommand::new().execute(&args_vec)
        },
        cli::Commands::Countme(_args) => {
            let mut args_vec = Vec::new();
            if _args.force { args_vec.push("--force".to_string()); }
            if _args.dry_run { args_vec.push("--dry-run".to_string()); }
            if _args.verbose { args_vec.push("--verbose".to_string()); }
            commands::telemetry::CountmeCommand::new().execute(&args_vec)
        },
        cli::Commands::Container(_args) => {
            let args_vec = vec!["container".to_string()];
            commands::container::ContainerCommand::new().execute(&args_vec)
        },
        cli::Commands::Testutils(args) => {
            #[cfg(feature = "development")]
            {
                match &args.subcommand {
                    cli::TestutilsSubcommands::InjectPkglist(inject_args) => {
                        let args_vec = vec!["inject-pkglist".to_string(), inject_args.repo.clone(), inject_args.refspec.clone()];
                        commands::testutils::TestutilsCommand::new().execute(&args_vec)
                    }
                    cli::TestutilsSubcommands::ScriptShell(shell_args) => {
                        let mut args_vec = vec!["script-shell".to_string()];
                        args_vec.push(shell_args.script.clone());
                        args_vec.extend(shell_args.args.clone());
                        
                        // Add rootpath
                        args_vec.push(shell_args.rootpath.clone());
                        
                        // Add optional flags
                        if shell_args.read_only {
                            args_vec.push("--read-only".to_string());
                        }
                        if let Some(ref user) = shell_args.user {
                            args_vec.push(format!("--user={}", user));
                        }
                        if let Some(ref group) = shell_args.group {
                            args_vec.push(format!("--group={}", group));
                        }
                        if let Some(ref cwd) = shell_args.cwd {
                            args_vec.push(format!("--cwd={}", cwd));
                        }
                        for env_var in &shell_args.env {
                            args_vec.push(format!("--env={}", env_var));
                        }
                        
                        commands::testutils::TestutilsCommand::new().execute(&args_vec)
                    }
                    cli::TestutilsSubcommands::GenerateSyntheticUpgrade(upgrade_args) => {
                        let mut args_vec = vec!["generate-synthetic-upgrade".to_string()];
                        args_vec.push(format!("--repo={}", upgrade_args.repo));
                        if let Some(ref src_ref) = upgrade_args.src_ref {
                            args_vec.push(format!("--srcref={}", src_ref));
                        }
                        args_vec.push(format!("--ref={}", upgrade_args.ostref));
                        args_vec.push(format!("--percentage={}", upgrade_args.percentage));
                        if let Some(ref version) = upgrade_args.commit_version {
                            args_vec.push(format!("--commit-version={}", version));
                        }
                        commands::testutils::TestutilsCommand::new().execute(&args_vec)
                    }
                    cli::TestutilsSubcommands::IntegrationReadOnly => {
                        let args_vec = vec!["integration-read-only".to_string()];
                        commands::testutils::TestutilsCommand::new().execute(&args_vec)
                    }
                    cli::TestutilsSubcommands::CUnits => {
                        let args_vec = vec!["c-units".to_string()];
                        commands::testutils::TestutilsCommand::new().execute(&args_vec)
                    }
                    cli::TestutilsSubcommands::Moo => {
                        let args_vec = vec!["moo".to_string()];
                        commands::testutils::TestutilsCommand::new().execute(&args_vec)
                    }
                }
            }
            #[cfg(not(feature = "development"))]
            {
                eprintln!("Development commands are not available. Build with --features development");
                std::process::exit(1);
            }
        },
        cli::Commands::ShlibBackend(args) => {
            #[cfg(feature = "development")]
            {
                match &args.subcommand {
                    cli::ShlibBackendSubcommands::GetBasearch => {
                        let args_vec = vec!["get-basearch".to_string()];
                        commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec)
                    }
                    cli::ShlibBackendSubcommands::VarsubstBasearch { source } => {
                        let args_vec = vec!["varsubst-basearch".to_string(), source.clone()];
                        commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec)
                    }
                    cli::ShlibBackendSubcommands::PackagelistFromCommit { commit } => {
                        let args_vec = vec!["packagelist-from-commit".to_string(), commit.clone()];
                        commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec)
                    }
                }
            }
            #[cfg(not(feature = "development"))]
            {
                eprintln!("Development commands are not available. Build with --features development");
                std::process::exit(1);
            }
        },
        cli::Commands::Internals(args) => {
            #[cfg(feature = "development")]
            {
                match &args.subcommand {
                    cli::InternalsSubcommands::Diagnostics => {
                        let args_vec = vec!["diagnostics".to_string()];
                        commands::internals::InternalsCommand::new().execute(&args_vec)
                    }
                    cli::InternalsSubcommands::ValidateState => {
                        let args_vec = vec!["validate-state".to_string()];
                        commands::internals::InternalsCommand::new().execute(&args_vec)
                    }
                    cli::InternalsSubcommands::DebugDump => {
                        let args_vec = vec!["debug-dump".to_string()];
                        commands::internals::InternalsCommand::new().execute(&args_vec)
                    }
                    cli::InternalsSubcommands::SystemHealth => {
                        let args_vec = vec!["system-health".to_string()];
                        commands::internals::InternalsCommand::new().execute(&args_vec)
                    }
                    cli::InternalsSubcommands::Performance => {
                        let args_vec = vec!["performance".to_string()];
                        commands::internals::InternalsCommand::new().execute(&args_vec)
                    }
                    cli::InternalsSubcommands::Security => {
                        let args_vec = vec!["security".to_string()];
                        commands::internals::InternalsCommand::new().execute(&args_vec)
                    }
                }
            }
            #[cfg(not(feature = "development"))]
            {
                eprintln!("Development commands are not available. Build with --features development");
                std::process::exit(1);
            }
        },
    };
    
    // Handle command result with appropriate exit codes
    match result {
        Ok(()) => {
            info!("apt-ostree completed successfully");
            process::exit(0);
        }
        Err(e) => {
            let exit_code = match e {
                AptOstreeError::PermissionDenied(ref msg) => {
                    eprintln!("❌ Permission denied: {}", msg);
                    eprintln!("💡 Try running with sudo or check Polkit authorization");
                    1
                }
                AptOstreeError::System(ref msg) => {
                    eprintln!("❌ System error: {}", msg);
                    1
                }
                AptOstreeError::PackageNotFound(ref pkg) => {
                    eprintln!("❌ Package not found: {}", pkg);
                    eprintln!("💡 Try 'apt search {}' to find available packages", pkg);
                    1
                }
                AptOstreeError::InvalidArgument(ref msg) => {
                    eprintln!("❌ Invalid argument: {}", msg);
                    eprintln!("💡 Use --help for usage information");
                    1
                }
                AptOstreeError::Ostree(ref msg) => {
                    eprintln!("❌ OSTree error: {}", msg);
                    eprintln!("💡 Check if OSTree is properly configured");
                    1
                }
                AptOstreeError::Apt(ref msg) => {
                    eprintln!("❌ APT error: {}", msg);
                    eprintln!("💡 Check APT configuration and package sources");
                    1
                }
                AptOstreeError::Transaction(ref msg) => {
                    eprintln!("❌ Transaction error: {}", msg);
                    eprintln!("💡 Check transaction status with 'apt-ostree transaction list'");
                    1
                }
                AptOstreeError::DaemonError(ref msg) => {
                    eprintln!("❌ Daemon error: {}", msg);
                    eprintln!("💡 Check daemon status: systemctl status apt-ostreed");
                    eprintln!("💡 Check daemon logs: journalctl -u apt-ostreed -f");
                    1
                }
                AptOstreeError::NoChange => {
                    // Special case: no changes made (exit code 77 like rpm-ostree)
                    println!("No changes.");
                    77
                }
                _ => {
                    eprintln!("❌ Unexpected error: {}", e);
                    1
                }
            };

            error!("apt-ostree failed with exit code {}: {}", exit_code, e);
            process::exit(exit_code);
        }
    }
}

// clap handles help and version automatically
