# OCI Registry Management Commands

use ../config/loader.nu get-config

# Start OCI registry
export def "oci-registry start" [
    --type: string = "zot"  # zot, harbor, distribution
    --config: string
    --detach (-d)
] {
    print $"🚀 Starting OCI registry \(($type)\)..."

    let registry_path = get-registry-path $type

    if not ($registry_path | path exists) {
        error make {
            msg: $"Registry path not found: ($registry_path)"
        }
    }

    cd $registry_path

    let compose_file = if ($config | is-empty) {
        "docker-compose.yml"
    } else {
        $config
    }

    let flags = if $detach { ["-d"] } else { [] }

    ^docker-compose -f $compose_file up ...$flags

    if $detach {
        print "✅ Registry started in background"
        print $"   Use 'oci-registry logs --type ($type)' to view logs"
        print $"   Use 'oci-registry status --type ($type)' to check status"
    }
}

# Stop OCI registry
export def "oci-registry stop" [
    --type: string = "zot"
    --remove-volumes (-v)
] {
    print $"🛑 Stopping OCI registry \(($type)\)..."

    let registry_path = get-registry-path $type

    cd $registry_path

    let flags = if $remove_volumes { ["-v"] } else { [] }

    ^docker-compose down ...$flags

    print "✅ Registry stopped"
}

# Get registry status
export def "oci-registry status" [
    --type: string = "zot"
    --format: string = "table"  # table, json
] -> any {
    let registry_path = get-registry-path $type

    cd $registry_path

    let containers = (^docker-compose ps --format json | from json)

    match $format {
        "json" => {
            $containers
        }
        "table" => {
            $containers | select Name State Status
        }
        _ => {
            $containers | select Name State Status
        }
    }
}

# Initialize registry (create namespaces, policies)
export def "oci-registry init" [
    --type: string = "zot"
    --registry-url: string = "localhost:5000"
    --admin-password: string = "admin"
    --skip-test
] {
    let script_path = $"(get-oci-registry-root)/scripts/init-registry.nu"

    let args = [
        "--registry-type" $type
        "--registry-url" $registry_url
        "--admin-password" $admin_password
    ]

    let args = if $skip_test {
        $args | append ["--skip-test"]
    } else {
        $args
    }

    nu $script_path ...$args
}

# Configure registry setting
export def "oci-registry configure" [
    --type: string = "zot"
    setting: string
    value: string
] {
    print $"⚙️  Configuring ($setting) = ($value)..."

    match $type {
        "zot" => {
            configure-zot-setting $setting $value
        }
        "harbor" => {
            configure-harbor-setting $setting $value
        }
        "distribution" => {
            configure-distribution-setting $setting $value
        }
        _ => {
            error make {
                msg: $"Unknown registry type: ($type)"
            }
        }
    }
}

# Get registry logs
export def "oci-registry logs" [
    --type: string = "zot"
    --follow (-f)
    --tail: int = 100
] {
    let registry_path = get-registry-path $type

    cd $registry_path

    let flags = if $follow {
        ["--follow", "--tail", ($tail | into string)]
    } else {
        ["--tail", ($tail | into string)]
    }

    ^docker-compose logs ...$flags
}

# Health check
export def "oci-registry health" [
    --type: string = "zot"
    --registry-url: string = "localhost:5000"
] -> record {
    print "🏥 Checking registry health..."

    let api_check = check-api-health $registry_url
    let catalog_check = check-catalog-health $registry_url
    let metrics_check = check-metrics-health $registry_url $type

    let overall = $api_check.healthy and $catalog_check.healthy

    {
        healthy: $overall
        api: $api_check
        catalog: $catalog_check
        metrics: $metrics_check
        timestamp: (date now | format date "%Y-%m-%d %H:%M:%S")
    }
}

# Push test image
export def "oci-registry test-push" [
    --registry-url: string = "localhost:5000"
] {
    print "🧪 Pushing test image..."

    # Pull hello-world
    ^docker pull hello-world:latest

    # Tag for our registry
    ^docker tag hello-world:latest $"($registry_url)/provisioning-test/hello:latest"

    # Push to registry
    ^docker push $"($registry_url)/provisioning-test/hello:latest"

    print "✅ Test image pushed successfully"
}

# Pull test image
export def "oci-registry test-pull" [
    --registry-url: string = "localhost:5000"
] {
    print "🧪 Pulling test image..."

    ^docker pull $"($registry_url)/provisioning-test/hello:latest"

    print "✅ Test image pulled successfully"
}

# List namespaces
export def "oci-registry namespaces" [
    --registry-url: string = "localhost:5000"
    --type: string = "zot"
] -> table {
    let result = (do {
        http get $"http://($registry_url)/v2/_catalog"
    } | complete)

    if $result.exit_code != 0 {
        error make {
            msg: $"Failed to fetch catalog: ($result.stderr)"
        }
    }

    let repos = ($result.stdout | from json | get repositories)
    let namespaces = ($repos | each { |repo|
        $repo | split row "/" | first
    } | uniq)

    $namespaces | each { |ns|
        let repo_count = ($repos | where { |r| $r | str starts-with $ns } | length)
        {
            namespace: $ns
            repositories: $repo_count
        }
    }
}

# Create namespace
export def "oci-registry namespace create" [
    name: string
    --registry-url: string = "localhost:5000"
    --type: string = "zot"
] {
    print $"📦 Creating namespace: ($name)..."

    match $type {
        "zot" => {
            print "  ℹ Namespace will be created on first push"
        }
        "harbor" => {
            create-harbor-namespace $registry_url $name
        }
        "distribution" => {
            print "  ℹ Namespace will be created on first push"
        }
        _ => {
            error make {
                msg: $"Unknown registry type: ($type)"
            }
        }
    }
}

# Delete namespace
export def "oci-registry namespace delete" [
    name: string
    --registry-url: string = "localhost:5000"
    --type: string = "zot"
    --force
] {
    if not $force {
        let confirm = (input $"⚠️  Delete namespace '($name)'? This will remove all images. \(y/N\): ")
        if $confirm != "y" {
            print "Cancelled"
            return
        }
    }

    print $"🗑️  Deleting namespace: ($name)..."

    match $type {
        "harbor" => {
            delete-harbor-namespace $registry_url $name
        }
        _ => {
            print $"  ⚠ Namespace deletion not supported for ($type)"
            print "    Delete all images manually and run garbage collection"
        }
    }
}

# Helper functions

def get-registry-path [type: string] -> string {
    let root = get-oci-registry-root
    $"($root)/($type)"
}

def get-oci-registry-root [] -> string {
    let config = (get-config)
    let base_path = ($config | get paths.base)
    $"($base_path)/provisioning/platform/oci-registry"
}

def check-api-health [registry_url: string] -> record {
    let result = (do {
        http get $"http://($registry_url)/v2/" --timeout 5sec
    } | complete)

    {
        healthy: ($result.exit_code == 0)
        message: (if $result.exit_code == 0 { "OK" } else { $result.stderr })
    }
}

def check-catalog-health [registry_url: string] -> record {
    let result = (do {
        http get $"http://($registry_url)/v2/_catalog" --timeout 5sec
    } | complete)

    {
        healthy: ($result.exit_code == 0)
        message: (if $result.exit_code == 0 { "OK" } else { $result.stderr })
    }
}

def check-metrics-health [registry_url: string, type: string] -> record {
    let metrics_url = match $type {
        "zot" => $"http://($registry_url)/metrics"
        "distribution" => $"http://($registry_url):5001/metrics"
        _ => null
    }

    if ($metrics_url | is-empty) {
        return {
            healthy: false
            message: "Metrics not supported"
        }
    }

    let result = (do {
        http get $metrics_url --timeout 5sec
    } | complete)

    {
        healthy: ($result.exit_code == 0)
        message: (if $result.exit_code == 0 { "OK" } else { "Not available" })
    }
}

def configure-zot-setting [setting: string, value: string] {
    print "  ℹ Zot configuration requires editing config.json and restarting"
    print $"    Setting: ($setting)"
    print $"    Value: ($value)"
}

def configure-harbor-setting [setting: string, value: string] {
    print "  ℹ Harbor configuration via API not fully implemented"
    print $"    Setting: ($setting)"
    print $"    Value: ($value)"
}

def configure-distribution-setting [setting: string, value: string] {
    print "  ℹ Distribution configuration requires editing config.yml and restarting"
    print $"    Setting: ($setting)"
    print $"    Value: ($value)"
}

def create-harbor-namespace [registry_url: string, name: string] {
    print "  ℹ Harbor project creation requires authentication"
    print $"    Run: oci-registry init --type harbor"
}

def delete-harbor-namespace [registry_url: string, name: string] {
    print "  ℹ Harbor project deletion requires authentication"
    print $"    Use Harbor UI or API with admin credentials"
}
