# Configuration Encryption CLI Commands
# Provides user-friendly commands for config encryption operations

use encryption.nu *
use accessor.nu *

# Encrypt a configuration file
export def "config encrypt" [
    file: path                  # Configuration file to encrypt
    --output (-o): path         # Output path (default: <file>.enc)
    --kms (-k): string = "age"  # KMS backend: age, aws-kms, vault, cosmian
    --in-place (-i)             # Encrypt in-place (overwrites original)
    --debug (-d)                # Enable debug output
] {
    if not ($file | path exists) {
        print $"❌ File not found: ($file)"
        return
    }

    print $"🔒 Encrypting configuration file: ($file)"
    print $"   Backend: ($kms)"

    if $in_place {
        print $"   Mode: In-place (will overwrite original)"
    } else if ($output | is-not-empty) {
        print $"   Output: ($output)"
    } else {
        print $"   Output: ($file).enc"
    }

    if $in_place and $debug {
        encrypt-config $file --kms $kms --debug true --in-place true
    } else if $in_place {
        encrypt-config $file --kms $kms --debug false --in-place true
    } else if $debug {
        encrypt-config $file $output --kms $kms --debug true --in-place false
    } else {
        encrypt-config $file $output --kms $kms --debug false --in-place false
    }
}

# Decrypt a configuration file
export def "config decrypt" [
    file: path          # Encrypted configuration file
    --output (-o): path # Output path (default: removes .enc extension)
    --in-place (-i)     # Decrypt in-place (overwrites original)
    --debug (-d)        # Enable debug output
] {
    if not ($file | path exists) {
        print $"❌ File not found: ($file)"
        return
    }

    print $"🔓 Decrypting configuration file: ($file)"

    if $in_place and $debug {
        decrypt-config $file --in-place true --debug true
    } else if $in_place {
        decrypt-config $file --in-place true --debug false
    } else if $debug {
        decrypt-config $file $output --in-place false --debug true
    } else {
        decrypt-config $file $output --in-place false --debug false
    }
}

# Edit encrypted configuration file securely
export def "config edit-secure" [
    file: path              # Encrypted configuration file
    --editor (-e): string   # Editor to use (default: $EDITOR or vim)
    --debug (-d)            # Enable debug output
] {
    if not ($file | path exists) {
        print $"❌ File not found: ($file)"
        return
    }

    if ($editor | is-not-empty) and $debug {
        edit-encrypted-config $file --editor $editor --debug true
    } else if ($editor | is-not-empty) {
        edit-encrypted-config $file --editor $editor --debug false
    } else if $debug {
        edit-encrypted-config $file --debug true
    } else {
        edit-encrypted-config $file --debug false
    }
}

# Rotate encryption keys for a configuration file
export def "config rotate-keys" [
    file: path          # Encrypted configuration file
    new_key: string     # New key ID or recipient
    --debug (-d)        # Enable debug output
] {
    if not ($file | path exists) {
        print $"❌ File not found: ($file)"
        return
    }

    print $"🔄 Rotating encryption keys"
    print $"   File: ($file)"
    print $"   New key: ($new_key)"

    if $debug {
        rotate-encryption-keys $file $new_key --debug true
    } else {
        rotate-encryption-keys $file $new_key --debug false
    }
}

# Check if a configuration file is encrypted
export def "config is-encrypted" [
    file: path  # Configuration file to check
] {
    if not ($file | path exists) {
        print $"❌ File not found: ($file)"
        return
    }

    let encrypted = (is-encrypted-config $file)

    if $encrypted {
        print $"🔒 File is encrypted: ($file)"
    } else {
        print $"🔓 File is not encrypted: ($file)"
    }

    $encrypted
}

# Validate encryption configuration and setup
export def "config validate-encryption" [] {
    print $"🔍 Validating encryption configuration..."
    print ""

    let validation = (validate-encryption-config)

    # Show summary
    print $"📊 Encryption Configuration Summary"
    print $"=================================="
    print $"   SOPS installed: ($validation.summary.sops_installed)"
    print $"   Age backend: ($validation.summary.age_backend)"
    print $"   KMS enabled: ($validation.summary.kms_enabled)"
    print $"   Errors: ($validation.summary.total_errors)"
    print $"   Warnings: ($validation.summary.total_warnings)"
    print ""

    # Show errors
    if ($validation.errors | length) > 0 {
        print $"❌ Errors:"
        for error in $validation.errors {
            print $"   • ($error.message)"
        }
        print ""
    }

    # Show warnings
    if ($validation.warnings | length) > 0 {
        print $"⚠️  Warnings:"
        for warning in $validation.warnings {
            print $"   • ($warning.message)"
        }
        print ""
    }

    if $validation.valid {
        print $"✅ Encryption configuration is valid"
    } else {
        print $"❌ Encryption configuration has errors"
    }

    $validation
}

# Scan directory for unencrypted sensitive configurations
export def "config scan-sensitive" [
    directory: path = "."   # Directory to scan
    --recursive (-r)        # Scan recursively
] {
    if not ($directory | path exists) {
        print $"❌ Directory not found: ($directory)"
        return
    }

    print $"🔍 Scanning for unencrypted sensitive configs in: ($directory)"

    let results = (scan-unencrypted-configs $directory --recursive=$recursive)

    if ($results | is-empty) {
        print $"✅ No unencrypted sensitive configs found"
    } else {
        print $"\n⚠️  Found ($results | length) unencrypted sensitive configs:"
        print ""
        print $results
        print ""
        print $"💡 Run 'config encrypt-all ($directory)' to encrypt them"
    }

    $results
}

# Encrypt all sensitive configurations in directory
export def "config encrypt-all" [
    directory: path = "."       # Directory to encrypt
    --kms (-k): string = "age"  # KMS backend: age, aws-kms, vault, cosmian
    --recursive (-r)            # Scan recursively
    --dry-run (-n)              # Dry run (no actual encryption)
] {
    if not ($directory | path exists) {
        print $"❌ Directory not found: ($directory)"
        return
    }

    if $recursive and $dry_run {
        encrypt-sensitive-configs $directory --kms $kms --recursive true --dry-run true
    } else if $recursive {
        encrypt-sensitive-configs $directory --kms $kms --recursive true --dry-run false
    } else if $dry_run {
        encrypt-sensitive-configs $directory --kms $kms --recursive false --dry-run true
    } else {
        encrypt-sensitive-configs $directory --kms $kms --recursive false --dry-run false
    }
}

# Show encryption information for configuration
export def "config encryption-info" [
    file: path  # Configuration file
] {
    if not ($file | path exists) {
        print $"❌ File not found: ($file)"
        return
    }

    print $"📋 Encryption Information"
    print $"========================"
    print $"   File: ($file)"

    let encrypted = (is-encrypted-config $file)
    print $"   Encrypted: ($encrypted)"

    if $encrypted {
        # Try to extract SOPS metadata
        let result = (do {
            let content = (open $file --raw)
            if ($content | str contains "sops:") {
                print $"   Type: SOPS encrypted"

                # Extract some metadata (without decrypting)
                if ($content | str contains "age:") {
                    print $"   Backend: Age"
                }
                if ($content | str contains "kms:") {
                    print $"   Backend: AWS KMS"
                }
                if ($content | str contains "vault:") {
                    print $"   Backend: Vault"
                }
            }
            "success"
        } | complete)

        if $result.exit_code != 0 {
            print $"   Type: Encrypted (unknown format)"
        }
    } else {
        let sensitive = (contains-sensitive-data $file)
        print $"   Contains sensitive data: ($sensitive)"

        if $sensitive {
            print ""
            print $"⚠️  This file contains sensitive data but is not encrypted!"
            print $"💡 Run 'config encrypt ($file)' to encrypt it"
        }
    }
}

# Initialize encryption setup (generate keys, create SOPS config)
export def "config init-encryption" [
    --kms (-k): string = "age"  # KMS backend to initialize: age, aws-kms, vault
    --force (-f)                # Force re-initialization
] {
    print $"🔧 Initializing encryption setup with ($kms)"
    print ""

    match $kms {
        "age" => {
            # Check if age is installed
            let age_check = (^which age | complete)
            if $age_check.exit_code != 0 {
                print $"❌ Age is not installed"
                print $"💡 Install with: brew install age"
                return
            }

            # Generate age key if not exists
            let age_key_file = ($env.HOME | path join ".config" | path join "sops" | path join "age" | path join "keys.txt")
            let age_key_dir = ($age_key_file | path dirname)

            if ($age_key_file | path exists) and not $force {
                print $"✅ Age key already exists: ($age_key_file)"
                print $"   Use --force to regenerate"
            } else {
                # Create directory
                mkdir $age_key_dir

                # Generate new age key
                print $"🔑 Generating new Age key..."
                let key_output = (^age-keygen -o $age_key_file | complete)

                if $key_output.exit_code == 0 {
                    print $"✅ Age key generated: ($age_key_file)"

                    # Extract recipient
                    let key_content = (open $age_key_file --raw)
                    let recipient = ($key_content | lines | where ($it | str starts-with "# public key:") | first | split row ": " | get 1)

                    print $"   Public key (recipient): ($recipient)"
                    print ""
                    print $"💡 Set this environment variable:"
                    print $"   export SOPS_AGE_RECIPIENTS=($recipient)"
                } else {
                    print $"❌ Failed to generate Age key"
                    return
                }
            }

            # Create .sops.yaml if not exists
            let sops_config = ($env.PWD | path join ".sops.yaml")
            if not ($sops_config | path exists) or $force {
                print $"📝 Creating SOPS configuration: ($sops_config)"

                let key_content = (open $age_key_file --raw)
                let recipient = ($key_content | lines | where ($it | str starts-with "# public key:") | first | split row ": " | get 1)

                let sops_yaml = $"creation_rules:
  - path_regex: .*\\.enc\\.yaml$
    age: ($recipient)
  - path_regex: .*\\.enc\\.yml$
    age: ($recipient)
  - path_regex: .*\\.enc\\.toml$
    age: ($recipient)
  - path_regex: .*\\.enc\\.json$
    age: ($recipient)
  - path_regex: workspace/.*/config/secure\\.yaml$
    age: ($recipient)
"

                $sops_yaml | save --force $sops_config
                print $"✅ SOPS configuration created"
            }
        }
        "aws-kms" => {
            print $"⚠️  AWS KMS requires manual configuration"
            print $"💡 Follow these steps:"
            print $"   1. Create KMS key in AWS Console"
            print $"   2. Update .sops.yaml with KMS ARN"
            print $"   3. Configure AWS credentials"
        }
        "vault" | "cosmian" => {
            print $"⚠️  ($kms) KMS requires manual configuration"
            print $"💡 Configure KMS settings in config file"
        }
        _ => {
            print $"❌ Unknown KMS backend: ($kms)"
            print $"   Supported: age, aws-kms, vault, cosmian"
        }
    }

    print ""
    print $"✅ Encryption initialization completed"
}

# Main help command
export def main [] {
    print "Configuration Encryption Commands"
    print "================================="
    print ""
    print "Encryption/Decryption:"
    print "  config encrypt <file>         Encrypt configuration file"
    print "  config decrypt <file>         Decrypt configuration file"
    print "  config edit-secure <file>     Edit encrypted file securely"
    print "  config rotate-keys <file>     Rotate encryption keys"
    print ""
    print "Information:"
    print "  config is-encrypted <file>    Check if file is encrypted"
    print "  config encryption-info <file> Show encryption details"
    print "  config validate-encryption    Validate encryption setup"
    print ""
    print "Bulk Operations:"
    print "  config scan-sensitive <dir>   Find unencrypted sensitive configs"
    print "  config encrypt-all <dir>      Encrypt all sensitive configs"
    print ""
    print "Setup:"
    print "  config init-encryption        Initialize encryption (generate keys)"
    print ""
    print "Examples:"
    print "  config encrypt workspace/config/secure.yaml"
    print "  config edit-secure workspace/config/secure.enc.yaml"
    print "  config scan-sensitive workspace/config --recursive"
    print "  config init-encryption --kms age"
}
