# Profile-based Access Control
# Implements permission system for restricted environments like CI/CD
# config/accessor star-import was dead — dropped (ADR-025 Phase 3 Layer 2).

# Load profile configuration
export def load-profile [profile_name?: string] {
    let active_profile = if ($profile_name | is-not-empty) {
        $profile_name
    } else {
        (get-provisioning-profile)
    }

    if ($active_profile | is-empty) {
        return {
            name: "default"
            allowed: {
                commands: []
                providers: []
                taskservs: []
            }
            blocked: {
                commands: []
                providers: []
                taskservs: []
            }
            restricted: false
        }
    }

    # Check user profile first
    let user_profile_path = ($env.HOME | path join ".provisioning-extensions" "profiles" $"($active_profile).yaml")
    let system_profile_path = ("/opt/provisioning-extensions/profiles" | path join $"($active_profile).yaml")
    let project_profile_path = ($env.PWD | path join ".provisioning" "profiles" $"($active_profile).yaml")

    # Load in priority order: project > user > system
    let available_files = [
        $project_profile_path
        $user_profile_path
        $system_profile_path
    ] | where ($it | path exists)

    if ($available_files | length) > 0 {
        open ($available_files | first)
    } else {
        # Default restricted profile
        {
            name: $active_profile
            allowed: {
                commands: ["list", "status", "show", "query", "help", "version"]
                providers: ["local"]
                taskservs: []
            }
            blocked: {
                commands: ["delete", "create", "sops", "secrets"]
                providers: ["aws", "upcloud"]
                taskservs: []
            }
            restricted: true
        }
    }
}

# Check if command is allowed
export def is-command-allowed [command: string, subcommand?: string] {
    let profile = (load-profile)

    if not $profile.restricted {
        return true
    }

    let full_command = if ($subcommand | is-not-empty) {
        $"($command) ($subcommand)"
    } else {
        $command
    }

    # Check blocked first
    if ($profile.blocked.commands | any {|cmd| $full_command =~ $cmd}) {
        return false
    }

    # If allowed list is empty, allow everything not blocked
    if ($profile.allowed.commands | is-empty) {
        return true
    }

    # Check if explicitly allowed
    ($profile.allowed.commands | any {|cmd| $full_command =~ $cmd})
}

# Check if provider is allowed
export def is-provider-allowed [provider: string] {
    let profile = (load-profile)

    if not $profile.restricted {
        return true
    }

    # Check blocked first
    if ($profile.blocked.providers | any {|prov| $provider == $prov}) {
        return false
    }

    # If allowed list is empty, allow everything not blocked
    if ($profile.allowed.providers | is-empty) {
        return true
    }

    # Check if explicitly allowed
    ($profile.allowed.providers | any {|prov| $provider == $prov})
}

# Check if taskserv is allowed
export def is-taskserv-allowed [taskserv: string] {
    let profile = (load-profile)

    if not $profile.restricted {
        return true
    }

    # Check blocked first
    if ($profile.blocked.taskservs | any {|ts| $taskserv == $ts}) {
        return false
    }

    # If allowed list is empty, allow everything not blocked
    if ($profile.allowed.taskservs | is-empty) {
        return true
    }

    # Check if explicitly allowed
    ($profile.allowed.taskservs | any {|ts| $taskserv == $ts})
}

# Enforce profile restrictions on command execution
export def enforce-profile [command: string, subcommand?: string, target?: string] {
    if not (is-command-allowed $command $subcommand) {
        print $"🛑 Command '($command) ($subcommand | default "")' is not allowed by profile ((get-provisioning-profile))"
        return false
    }

    # Additional checks based on target type
    if ($target | is-not-empty) {
        match $command {
            "server" => {
                if ($subcommand | default "") in ["create", "delete"] {
                    let settings = (find_get_settings)
                    let server = ($settings.data.servers | where hostname == $target | first?)
                    if ($server | is-not-empty) {
                        if not (is-provider-allowed $server.provider) {
                            print $"🛑 Provider '($server.provider)' is not allowed by profile"
                            return false
                        }
                    }
                }
            }
            "taskserv" => {
                if not (is-taskserv-allowed $target) {
                    print $"🛑 TaskServ '($target)' is not allowed by profile"
                    return false
                }
            }
        }
    }

    return true
}

# Show current profile information
export def show-profile [] {
    let profile = (load-profile)
    {
        active_profile: (get-provisioning-profile)
        extension_mode: (get-extension-mode)
        profile_config: $profile
        status: (if $profile.restricted { "restricted" } else { "unrestricted" })
    }
}

# Create example profile files
export def create-example-profiles [] {
    let user_profiles_dir = ($env.HOME | path join ".provisioning-extensions" "profiles")
    mkdir $user_profiles_dir

    # CI/CD profile
    let cicd_profile = {
        profile: "cicd"
        description: "Restricted profile for CI/CD agents"
        restricted: true
        allowed: {
            commands: ["server list", "server status", "taskserv list", "taskserv status", "query", "show", "help", "version"]
            providers: ["local"]
            taskservs: ["kubernetes", "containerd", "kubectl"]
        }
        blocked: {
            commands: ["server create", "server delete", "taskserv create", "taskserv delete", "sops", "secrets"]
            providers: ["aws", "upcloud"]
            taskservs: ["postgres", "gitea"]
        }
    }

    # Developer profile
    let developer_profile = {
        profile: "developer"
        description: "Profile for developers with limited production access"
        restricted: true
        allowed: {
            commands: ["server list", "server create", "taskserv list", "taskserv create", "query", "show"]
            providers: ["local", "aws"]
            taskservs: []
        }
        blocked: {
            commands: ["server delete", "sops"]
            providers: ["upcloud"]
            taskservs: ["postgres"]
        }
    }

    # Save example profiles
    $cicd_profile | to yaml | save ($user_profiles_dir | path join "cicd.yaml")
    $developer_profile | to yaml | save ($user_profiles_dir | path join "developer.yaml")

    print $"Created example profiles in ($user_profiles_dir)"
}
