# CoreDNS Docker Management
# Manage CoreDNS in Docker containers using docker-compose

# ../utils/log.nu does not exist — dangling import removed (ADR-025 L2).
use lib_provisioning/coredns/corefile.nu [generate-corefile write-corefile]
use zones.nu create-zone-file

# Start CoreDNS Docker container
export def "coredns docker start" [
    --check
] {
    log info "Starting CoreDNS Docker container"

    if $check {
        print "Check mode: Would start CoreDNS Docker container"
        return
    }

    let compose_file = get-compose-file-path

    if not ($compose_file | path exists) {
        log error $"docker-compose.yml not found at ($compose_file)"
        print "Error: docker-compose.yml not found"
        print $"Expected location: ($compose_file)"
        exit 1
    }

    # Ensure configuration exists
    ensure-coredns-config

    let result = (do {
        docker-compose -f $compose_file up -d
    } | complete)

    if $result.exit_code == 0 {
        print "✓ CoreDNS Docker container started"
        print ""
        print "Check status with: provisioning dns docker status"
        print "View logs with: provisioning dns docker logs"
    } else {
        log error "Failed to start CoreDNS Docker container"
        print "✗ Failed to start CoreDNS Docker container"
        exit 1
    }
}

# Stop CoreDNS Docker container
export def "coredns docker stop" [
    --check
] {
    log info "Stopping CoreDNS Docker container"

    if $check {
        print "Check mode: Would stop CoreDNS Docker container"
        return
    }

    let compose_file = get-compose-file-path

    let result = (do {
        docker-compose -f $compose_file down
    } | complete)

    if $result.exit_code == 0 {
        print "✓ CoreDNS Docker container stopped"
    } else {
        log error "Failed to stop CoreDNS Docker container"
        print "✗ Failed to stop CoreDNS Docker container"
        exit 1
    }
}

# Restart CoreDNS Docker container
export def "coredns docker restart" [
    --check
] {
    log info "Restarting CoreDNS Docker container"

    if $check {
        print "Check mode: Would restart CoreDNS Docker container"
        return
    }

    let compose_file = get-compose-file-path

    let result = (do {
        docker-compose -f $compose_file restart
    } | complete)

    if $result.exit_code == 0 {
        print "✓ CoreDNS Docker container restarted"
    } else {
        log error "Failed to restart CoreDNS Docker container"
        print "✗ Failed to restart CoreDNS Docker container"
        exit 1
    }
}

# Show CoreDNS Docker container status
export def "coredns docker status" [] {
    let compose_file = get-compose-file-path

    print "CoreDNS Docker Status\n=====================\n"

    let ps_result = (do {
        docker-compose -f $compose_file ps
    } | complete)

    if $ps_result.exit_code == 0 {
        print $ps_result.stdout
    } else {
        print "✗ Failed to get status (docker-compose may not be available)"
    }

    print "\nContainer Details:\n"

    let details_result = (do {
        docker ps --filter "name=provisioning-coredns" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
    } | complete)

    if $details_result.exit_code == 0 {
        print $details_result.stdout
    } else {
        print "✗ Failed to get container details"
    }
}

# Show CoreDNS Docker container logs
export def "coredns docker logs" [
    --follow (-f)       # Follow log output
    --lines: int = 50   # Number of lines to show
] {
    let compose_file = get-compose-file-path

    let result = (do {
        if $follow {
            docker-compose -f $compose_file logs -f --tail $lines
        } else {
            docker-compose -f $compose_file logs --tail $lines
        }
    } | complete)

    if $result.exit_code != 0 {
        log error "Failed to get CoreDNS Docker logs"
        print "✗ Failed to get logs"
        exit 1
    }
}

# Execute command in CoreDNS Docker container
export def "coredns docker exec" [
    ...command: string  # Command to execute
] {
    let compose_file = get-compose-file-path

    let result = (do {
        docker-compose -f $compose_file exec coredns ...$command
    } | complete)

    if $result.exit_code != 0 {
        log error "Failed to execute command in CoreDNS Docker container"
        print "✗ Failed to execute command"
        exit 1
    }
}

# Pull latest CoreDNS Docker image
export def "coredns docker pull" [
    --version: string = "1.11.1"
] {
    log info $"Pulling CoreDNS Docker image: ($version)"

    let result = (do {
        docker pull $"coredns/coredns:($version)"
    } | complete)

    if $result.exit_code == 0 {
        print $"✓ CoreDNS Docker image pulled: ($version)"
    } else {
        log error "Failed to pull CoreDNS Docker image"
        print "✗ Failed to pull image"
        exit 1
    }
}

# Update CoreDNS Docker container to latest version
export def "coredns docker update" [
    --version: string = "latest"
    --check
] {
    log info "Updating CoreDNS Docker container"

    if $check {
        print "Check mode: Would update CoreDNS Docker container"
        return
    }

    # Pull new image
    coredns docker pull --version $version

    # Restart with new image
    coredns docker restart

    print "✓ CoreDNS Docker container updated"
}

# Show CoreDNS Docker container health
export def "coredns docker health" [] {
    let health = (do {
        docker inspect provisioning-coredns --format "{{.State.Health.Status}}"
    } | complete)

    if $health.exit_code == 0 {
        let status = $health.stdout | str trim

        print $"Health Status: ($status)"

        match $status {
            "healthy" => { print "✓ Container is healthy" }
            "unhealthy" => { print "✗ Container is unhealthy" }
            "starting" => { print "⏳ Container is starting" }
            _ => { print $"Unknown status: ($status)" }
        }
    } else {
        print "✗ Container not found or no health check configured"
    }
}

# Remove CoreDNS Docker container and volumes
export def "coredns docker remove" [
    --volumes (-v)  # Remove volumes as well
    --force         # Skip confirmation
    --check
] {
    if not $force {
        let confirm = input "Are you sure you want to remove CoreDNS Docker container? (yes/no): "

        if $confirm != "yes" {
            print "Cancelled"
            return
        }
    }

    if $check {
        print "Check mode: Would remove CoreDNS Docker container"
        return
    }

    let compose_file = get-compose-file-path

    let result = (do {
        if $volumes {
            docker-compose -f $compose_file down -v
        } else {
            docker-compose -f $compose_file down
        }
    } | complete)

    if $result.exit_code == 0 {
        if $volumes {
            print "✓ CoreDNS Docker container and volumes removed"
        } else {
            print "✓ CoreDNS Docker container removed"
        }
    } else {
        log error "Failed to remove CoreDNS Docker container"
        print "✗ Failed to remove container"
        exit 1
    }
}

# Helper: Get docker-compose file path
def get-compose-file-path [] -> string {
    let project_root = get-project-root
    $"($project_root)/provisioning/config/coredns/docker-compose.yml"
}

# Helper: Get project root
def get-project-root [] -> string {
    # Try to find project root by looking for provisioning directory
    mut current = pwd

    loop {
        if ($"($current)/provisioning" | path exists) {
            return $current
        }

        let parent = $current | path dirname

        if $parent == $current {
            # Reached filesystem root
            break
        }

        $current = $parent
    }

    # Fallback: use current directory
    pwd
}

# Helper: Ensure CoreDNS configuration exists
def ensure-coredns-config [] {
    let config_dir = $"([$env.HOME, '.provisioning', 'coredns'] | path join)"
    let corefile_path = $"($config_dir)/Corefile"
    let zones_path = $"($config_dir)/zones"

    # Create directories
    mkdir $config_dir
    mkdir $zones_path

    # Generate Corefile if not exists
    if not ($corefile_path | path exists) {
        log info "Generating default Corefile"

        let default_config = {
            mode: "local"
            local: {
                port: 5353
                zones_path: $zones_path
                zones: ["provisioning.local"]
            }
            upstream: ["8.8.8.8", "1.1.1.1"]
            enable_logging: true
        }

        let corefile_content = generate-corefile $default_config
        write-corefile $corefile_path $corefile_content
    }

    # Create zone files if not exist
    let zones = ["provisioning.local"]

    for zone in $zones {
        let zone_file = $"($zones_path)/($zone).zone"

        if not ($zone_file | path exists) {
            log info $"Creating default zone file: ($zone)"
            create-zone-file $zone $zones_path
        }
    }
}

# Show docker-compose configuration
export def "coredns docker config" [] {
    let compose_file = get-compose-file-path

    if not ($compose_file | path exists) {
        print $"✗ docker-compose.yml not found at ($compose_file)"
        exit 1
    }

    print $"Docker Compose Configuration\n============================\n"
    print $"File: ($compose_file)\n"

    docker-compose -f $compose_file config
}
