#!/bin/env bash

# SPDX-FileCopyrightText: 2023 - 2025 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-or-later

# linglong cli completion

#set -x

__ll_cli_get_container_list() {
        ll-cli ps | tail -n+2 | awk '{print $1}' | tr '\n' ' '
}

__ll_cli_get_installed_app_list() {
        ll-cli list --type=app | tail -n+2 | awk '{print $1}' | tr '\n' ' '
}

__ll_cli_get_installed_list() {
        ll-cli list | tail -n+2 | awk '{print $1}' | tr '\n' ' '
}

__ll_cli_get_app_list() {
        ll-cli search $1 | tail -n+2 | awk '{print $1}' | sort | uniq | tr '\n' ' '
}

__ll_cli_get_layer_list() {
        ls $1*.layer 2>/dev/null | tr '\n' ' '
}

__ll_cli_get_repo_alias_list() {
        ll-cli repo show | tail -n+3 | awk '{print $3}' | tr "\n" " "
}

# 只补全当前目录下的 .layer 和 .uab 文件，不包括目录
__ll_cli_get_layer_uab_files_bash() {
    local cur="$1"
    local dir="${cur%/*}"
    [[ "$cur" == */* ]] || dir="."
    find "$dir" -maxdepth 1 -type f \( -name '*.layer' -o -name '*.uab' \) -printf '%P\n'
}

__filter_exist_options() {
        local aviable_opts
        for opt in $1; do
                local blank=" "
                for word in "${COMP_WORDS[@]}"; do
                        if [[ "x${word}" == "x${opt}" ]]; then
                                opt=""
                                blank=""
                                break
                        fi
                done
                aviable_opts+="${opt}"
                aviable_opts+="${blank}"
        done
        echo ${aviable_opts}
}

_ll_cli_complete() {
        local cur prev output_options subcommand
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD - 1]}"

        # Define the options and subcommands
        local common_options="-h --help --help-all"
        local global_options="--version --json"
        local subcommands="run ps enter kill prune install uninstall upgrade list info content search repo"

        output_options="$common_options"
        # For the first word (command or options)
        if [[ ${COMP_CWORD} -lt 2 ]]; then
                output_options="${output_options} ${global_options} ${subcommands}"
                COMPREPLY=($(compgen -W "${output_options}" -- "${cur}"))
                return 0
        elif [[ ${COMP_CWORD} -eq 2 && ${COMP_WORDS[1]} == -* ]]; then
                output_options="${output_options} ${subcommands}"
                COMPREPLY=($(compgen -W "${output_options}" -- "${cur}"))
                return 0
        fi

        if [[ ${COMP_WORDS[1]} != -* ]]; then
                subcommand=${COMP_WORDS[1]}
        else
                subcommand=${COMP_WORDS[2]}
        fi

        case ${subcommand} in
        run)
                local run_options="--file --url"
                local installed_list
                if [[ "${prev}" == "run" ]]; then
                        installed_list="$(__ll_cli_get_installed_app_list)"
                fi
                output_options="${output_options} ${run_options} ${installed_list}"
                ;;
        ps)
                # Nothing here
                ;;
        enter)
                local enter_options="--working-directory"
                local container_list
                if [[ "${prev}" == "enter" ]]; then
                        container_list="$(__ll_cli_get_container_list)"
                fi
                output_options="${output_options} ${enter_options} ${container_list}"
                ;;
        kill)
                output_options="${output_options} $(__ll_cli_get_container_list)"
                ;;
        prune)
                # Nothing here
                ;;
        install)
                install_options="--module --force -y"
                # 判断当前补全文本是否以 ./ 开头，若是则只补全本地layer/uab文件且不补全目录
                if [[ "$cur" == ./* ]]; then
                    local dir prefix files
                    if [[ "$cur" == */* ]]; then
                        dir="${cur%/*}"
                        prefix="${dir}/"
                    else
                        dir="."
                        prefix=""
                    fi
                    # 列出目录下 .layer 和 .uab 文件，只要文件不要目录
                    files=$(find "$dir" -maxdepth 1 -type f \( -name '*.layer' -o -name '*.uab' \) -printf '%f\n')
                    # 拼回补全前缀
                    files=$(printf "%s\n" $files | sed "s|^|$prefix|")
                    COMPREPLY=( $(compgen -W "$files" -- "$cur") )
                    return 0
                else
                    search_target="."
                    if [[ -n "${cur}" ]]; then
                        search_target=${cur}
                    fi
                    local app_list
                    if [[ "${prev}" == "install" ]]; then
                        app_list="$(__ll_cli_get_app_list "${search_target}")"
                    fi
                    output_options="${output_options} ${install_options} ${app_list}"
                fi
                ;;
        uninstall)
                local uninstall_options
                local installed_list
                if [[ "${prev}" == "uninstall" ]]; then
                        installed_list="$(__ll_cli_get_installed_app_list)"
                fi
                output_options="${output_options} ${uninstall_options} ${installed_list}"
                ;;
        upgrade)
                output_options="${output_options} $(__ll_cli_get_installed_list)"
                ;;
        list)
                list_options="--type --upgradable"
                output_options="${output_options} ${list_options}"
                ;;
        info)
                output_options="${output_options} $(__ll_cli_get_installed_list) $(__ll_cli_get_layer_list ${cur}))"
                ;;
        content)
                output_options="${output_options} $(__ll_cli_get_installed_app_list)"
                ;;
        search)
                search_target="."
                if [[ x${cur} != x ]]; then
                        search_target=${cur}
                fi
                search_options="--type --dev"
                output_options="${output_options} ${search_options} $(__ll_cli_get_app_list ${search_target})"
                ;;
        repo)
                local repo_subcommands="add remove update set-default show"
                if [[ ${prev} == "repo" ]]; then
                        output_options="${output_options} ${repo_subcommands}"
                fi

                if [[ ${prev} == "remove" || ${prev} == "set-default" ]]; then
                        output_options="${output_options} $(__ll_cli_get_repo_alias_list)"
                fi
                ;;
        esac

        output_options="$(__filter_exist_options "${output_options}")"
        COMPREPLY=($(compgen -W "${output_options}" -- "${cur}"))

        return 0
}

complete -F _ll_cli_complete ll-cli
