#!/bin/bash

# ============================================================
# KARE bash completion — 支持新旧 CLI 命令
# ============================================================

envList="ubuntu16.04 ubuntu18.04 ubuntu20.04 ubuntu22.04 ubuntu24.04 v10 v10sp1 shadow openkylin1.0 openkylin2.0"

# ---- 辅助函数 ----

# 获取已安装的软件包列表（通过 kare -l）
function _comp_kare_installed_packages () {
    packagelist=()
    while IFS= read -r line; do
        clean_line=$(echo "$line" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g')
        clean_col1=$(echo "$clean_line" | awk '{gsub(/^[[:space:]]+|[[:space:]]+$/,""); print $1}')
        [[ -z $clean_col1 ]] && continue
        packagelist+=("$clean_col1")
    done < <(kare -l 2>/dev/null | tail -n +3)
    set -f
    echo "${packagelist[*]}"
    set +f
}

# 获取已构建的基础环境/运行环境名称列表
function _comp_kare_envs () {
    local envs
    # 优先从 release.json 读取，失败则回退到 kare -E
    if [ -r /opt/kare-applications/config/release.json ]; then
        envs=$(python3 -c "
import json
try:
    with open('/opt/kare-applications/config/release.json') as f:
        data = json.load(f)
    print(' '.join(data.keys()))
except: pass
" 2>/dev/null)
    fi
    if [ -z "$envs" ]; then
        envs=$(kare -E 2>/dev/null)
    fi
    echo "$envs"
}

# 获取已安装的应用包名（排除系统包）
function _comp_kare_app_packages () {
    python3 -c "
import json
SKIP = ('v10sp1Driver','dkmsContainer','shadowDriver','upgradeContainer')
try:
    with open('/opt/kare-applications/config/install.json') as f:
        data = json.load(f)
    for pkg in sorted(data):
        if pkg not in SKIP:
            print(pkg)
except: pass
" 2>/dev/null
}

# 获取运行环境名称（同 base 环境）
function _comp_kare_runtime_names () {
    _comp_kare_envs
}

# 文件补全（deb 文件）
function _comp_kare_deb_files () {
    local cur="$1"
    _filedir '?(u|d)deb'
}

# ---- 主补全函数 ----

function _kare() {
    local cur prev words cword
    COMPREPLY=()

    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD - 1]}"

    _init_completion -s || return

    # ---- 解析命令行层级，定位当前上下文 ----
    local cmd=""        # 顶层子命令: base / runtime / app / run / inspect / ...
    local action=""     # 第二层动作: list / install / remove / config / ...
    local subaction=""  # 第三层动作: show / set / get / reset / add / ...

    local i
    for (( i = 1; i < cword; i++ )); do
        local w="${words[i]}"
        # 跳过选项和它们的参数
        case "$w" in
            -e|--env|-b|--subsystem|-p|--dir|-n|--lines|--level|--config)
                (( i++ ))  # 跳过选项值
                continue
                ;;
            -*) continue ;;
        esac

        if [ -z "$cmd" ]; then
            cmd="$w"
        elif [ -z "$action" ]; then
            action="$w"
        elif [ -z "$subaction" ]; then
            subaction="$w"
        fi
    done

    # ---- 先处理旧式基于 prev 的选项补全（在 cmd 为空时） ----
    case "$prev" in
        -b)
            COMPREPLY=($(compgen -W "${envList}" -- "$cur"))
            return
            ;;
        --subsystem)
            COMPREPLY=($(compgen -W "cups dkms" -- "$cur"))
            return
            ;;
        -e|--env)
            COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            return
            ;;
        -L|-P|-S|-r|-f)
            COMPREPLY=($(compgen -W "$(_comp_kare_installed_packages)" -- "$cur"))
            return
            ;;
        -i|install)
            _filedir '?(u|d)deb'
            return
            ;;
    esac

    # ---- 根据上下文补全 ----

    # === 顶层：没有子命令时，补全顶层选项和子命令 ===
    if [ -z "$cmd" ]; then
        local top_cmds="base runtime app health run inspect import clear_base_apply restore_apply try-install addrepo update-source download update-config"
        local top_opts="-i -e -E -b -l -L -P -S -h -f -r -p -m --chroot --subsystem --multi-env"
        COMPREPLY=($(compgen -W "${top_opts} ${top_cmds}" -- "$cur"))
        return
    fi

    # === 处理旧式顶层子命令 ===
    case "$cmd" in
        run)
            # run 后面补全已安装的包名
            COMPREPLY=($(compgen -W "$(_comp_kare_installed_packages)" -- "$cur"))
            return
            ;;
        inspect)
            COMPREPLY=($(compgen -W "$(_comp_kare_installed_packages)" -- "$cur"))
            return
            ;;
        import)
            # import 后面可能需要文件路径
            _filedir
            return
            ;;
        install)
            _filedir '?(u|d)deb'
            return
            ;;
        remove)
            COMPREPLY=($(compgen -W "$(_comp_kare_installed_packages)" -- "$cur"))
            return
            ;;
        try-install)
            if [ "$prev" = "--env" ]; then
                COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            fi
            return
            ;;
        addrepo)
            if [ "$prev" = "--env" ]; then
                COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            fi
            return
            ;;
        update-source)
            if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            fi
            return
            ;;
        download)
            if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            fi
            return
            ;;
        update-config)
            return
            ;;
        clear_base_apply)
            COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            return
            ;;
        restore_apply)
            COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
            return
            ;;
    esac

    # ================================================================
    #  新 CLI: kare base ...
    # ================================================================
    if [ "$cmd" = "base" ]; then
        if [ -z "$action" ]; then
            COMPREPLY=($(compgen -W "list info build rebuild destroy" -- "$cur"))
            return
        fi
        case "$action" in
            list)
                return
                ;;
            info|build|rebuild|destroy)
                COMPREPLY=($(compgen -W "$(_comp_kare_envs)" -- "$cur"))
                return
                ;;
        esac
        return
    fi

    # ================================================================
    #  新 CLI: kare runtime ...
    # ================================================================
    if [ "$cmd" = "runtime" ]; then
        if [ -z "$action" ]; then
            COMPREPLY=($(compgen -W "list info patch exec shell sources share env cp" -- "$cur"))
            return
        fi

        case "$action" in
            list)
                return
                ;;
            info|patch|exec|shell)
                COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                return
                ;;
            cp)
                # cp 接受 src dst，格式可能是 rt:path 或普通路径
                return
                ;;

            # ---- runtime sources ----
            sources)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "list add remove update" -- "$cur"))
                    return
                fi
                case "$subaction" in
                    list|add|remove|update)
                        COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                        return
                        ;;
                esac
                return
                ;;

            # ---- runtime share ----
            share)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "list add remove readonly readwrite" -- "$cur"))
                    return
                fi
                case "$subaction" in
                    list|add|remove|readonly|readwrite)
                        COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                        return
                        ;;
                esac
                return
                ;;

            # ---- runtime env ----
            env)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "list set unset" -- "$cur"))
                    return
                fi
                case "$subaction" in
                    list|set|unset)
                        COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                        return
                        ;;
                esac
                return
                ;;
        esac
        return
    fi

    # ================================================================
    #  新 CLI: kare app ...
    # ================================================================
    if [ "$cmd" = "app" ]; then
        if [ -z "$action" ]; then
            COMPREPLY=($(compgen -W "install remove list info size which download shell exec stop share env depends check" -- "$cur"))
            return
        fi

        case "$action" in
            # ---- app install ----
            install)
                if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                    COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                else
                    _filedir '?(u|d)deb'
                fi
                return
                ;;

            # ---- app remove / shell / exec / stop / info / size ----
            remove|shell|exec|stop|info|size)
                if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                    COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                else
                    COMPREPLY=($(compgen -W "$(_comp_kare_app_packages)" -- "$cur"))
                fi
                return
                ;;

            # ---- app list ----
            list)
                if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                    COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                fi
                return
                ;;

            # ---- app which ----
            which)
                _filedir
                return
                ;;

            # ---- app download ----
            download)
                if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                    COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                elif [ "$prev" = "--dir" ]; then
                    _filedir -d
                else
                    COMPREPLY=($(compgen -W "$(_comp_kare_app_packages)" -- "$cur"))
                fi
                return
                ;;

            # ---- app share ----
            share)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "list add remove" -- "$cur"))
                    return
                fi
                if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                    COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                elif [ "$prev" = "--ro" ]; then
                    # --ro 是 flag，后面不需要补全
                    return
                else
                    COMPREPLY=($(compgen -W "$(_comp_kare_app_packages)" -- "$cur"))
                fi
                return
                ;;

            # ---- app env ----
            env)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "list set unset" -- "$cur"))
                    return
                fi
                if [ "$prev" = "-e" ] || [ "$prev" = "--env" ]; then
                    COMPREPLY=($(compgen -W "$(_comp_kare_runtime_names)" -- "$cur"))
                else
                    COMPREPLY=($(compgen -W "$(_comp_kare_app_packages)" -- "$cur"))
                fi
                return
                ;;

            # ---- app depends ----
            depends)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "list add remove" -- "$cur"))
                    return
                fi
                COMPREPLY=($(compgen -W "$(_comp_kare_app_packages)" -- "$cur"))
                return
                ;;

            # ---- app check ----
            check)
                if [ -z "$subaction" ]; then
                    COMPREPLY=($(compgen -W "deb list-rules" -- "$cur"))
                    return
                fi
                case "$subaction" in
                    deb)
                        if [ "$prev" = "--level" ]; then
                            COMPREPLY=($(compgen -W "force warn all" -- "$cur"))
                        elif [ "$prev" = "--config" ]; then
                            _filedir 'json'
                        elif [[ "$cur" == -* ]]; then
                            COMPREPLY=($(compgen -W "--level --config --json --verbose" -- "$cur"))
                        else
                            # 补全 deb 路径（目录可进入，.deb/.udeb）
                            _filedir '?(u|d)deb'
                        fi
                        return
                        ;;
                    list-rules)
                        if [ "$prev" = "--config" ]; then
                            _filedir 'json'
                        else
                            COMPREPLY=($(compgen -W "--config --json" -- "$cur"))
                        fi
                        return
                        ;;
                esac
                return
                ;;
        esac
        return
    fi

    # ---- 兜底：其他未知情况不作补全 ----
    return
} &&
    complete -F _kare kare
