# shellcheck shell=dash

# Note: `x skill use` lives in lib/use. It wraps this function with --global
# semantics and TSV tracking at ${HOME}/.local/data/x-skill/use.list.tsv.

___x_cmd_skill_add(){
    local dir=""
    local skills=""
    local agent=""
    local scope="project"
    local nocache=0

    while [ "$#" -gt 0 ]; do
        case "$1" in
            -h|--help)      ___x_cmd help -m skill add;             return 0 ;;
            --skill-dir)    dir="$2";           arg:2:shift ;;
            -a|--agent)     agent="$2";         arg:2:shift ;;
            -s|--skill)     skills="${skills}${2}${___X_CMD_UNSEENCHAR_NEWLINE}";
                                                arg:2:shift ;;
            -g|--global)    scope=global;       shift ;;
            -p|--project)   scope=project;      shift ;;
            --no-cache)     nocache=1;          shift ;;
            --)             shift; break ;;
            -*)             N=skill M="Unknown option: $1" log:ret:1 ;;
            *)
                            set -- "$@" "--"
                            while [ $# -gt 0 ]; do
                                case "$1" in
                                    -*) break ;;
                                esac
                                set -- "$@" "$1"
                                shift
                            done
                            ;;
        esac
    done
    skills="${skills%"${___X_CMD_UNSEENCHAR_NEWLINE}"}"

    ___x_cmd_skill___data_check             || return $?

    if [ -n "$dir" ]; then
        ___x_cmd_skill_add___dispatch "$dir" "$@"
    elif [ -n "$agent" ]; then
        case "$agent" in
            claude)         dir=".claude/skills" ;;
            *)              dir=".agents/skills" ;;
        esac
        [ "$scope" = "project" ] || dir="$HOME/$dir"
        ___x_cmd_skill_add___dispatch "$dir" "$@"
    else
        local _dirbase
        [ "$scope" = "project" ] && _dirbase="." || _dirbase="$HOME"
        ___x_cmd_skill_add___dispatch "$_dirbase/.agents/skills" "$@"
        ___x_cmd_skill_add___dispatch "$_dirbase/.claude/skills" --skip-mcp "$@"
    fi
}

___x_cmd_skill_add___dispatch(){
    local dir="$1"; shift
    local skip_mcp=0

    case "$1" in
        --skip-mcp) skip_mcp=1; shift ;;
    esac

    case "$1" in
        https://github.com/*)
            ___x_cmd_skill_add___fromgithub "$dir" "$1" "$skills" "$nocache" || return $?
            ;;
        *)
            local i=
            for i in "$@"; do
                case "$i" in
                    mcp/*)
                        [ "$skip_mcp" = 1 ] && continue
                        ___x_cmd_skill_add___mcp "$scope" "$i" || return $?
                        ;;
                    clawhub/*)  ___x_cmd_skill_add___fromclawhub "$dir" "$i" "$nocache" || return $?  ;;
                    x-mod/*)    ___x_cmd_skill_add___fromxmod   "$dir" "$i"             || return $?  ;;
                    *)          ___x_cmd_skill_add___fromawsome "$dir" "$i"             || return $?  ;;
                esac
            done
            ;;
    esac
}

___x_cmd_skill_add___mcp(){
    local scope="$1"
    local mcpid="$2"

    [ "$scope" != "project" ] || scope="user"
    local name="${mcpid#mcp/*}"

    local config; config="$(___x_cmd jq -c --arg name "$name" '.[$name]? | (.stdio // .http)' "$___X_CMD_SKILL_FULL_MCP_FILE" )"
    [ "$config" != 'null' ] || {
            skill:error "Not found MCP[$mcpid]"
            return 1
    }

    local IFS=; local id=; local reference=; local desc=; local _
    while IFS="$___X_CMD_UNSEENCHAR_HT" read -r id _ reference _ _ _ _ desc; do
        if [ "$id" = "$mcpid" ]; then
            skill:info --reference "$reference" --description "$desc" "Loading MCP configuration."
            break
        fi
    done < "$___X_CMD_SKILL_FULL_INDEX_FILE"

    ___x_cmd claude -- mcp add-json --scope "$scope" "$name" "${config}" || {
        skill:error "Failed to add MCP[$mcpid] to $scope scope"
        return 1
    }

    skill:info "Successfully added MCP[$mcpid] to $scope scope"
    case "$scope" in
        project)  skill:info "Config file: .mcp.json" ;;
        *)        skill:info "Config file: ~/.claude.json" ;;
    esac
}

___x_cmd_skill_add___fromawsome(){
    local dir="$1";     [ -n "$dir" ]     || N=skill M="Please provide the dir" log:ret:64
    local skillid="$2"; [ -n "$skillid" ] || N=skill M="Please provide the skill id" log:ret:64

    local datadir="$___X_CMD_SKILL_FULL_DATA_DIR/$skillid"

    local x_id=""; local x_url=""; local x_reference=""; local x_license=""
    local x_name=""; local x_author=""; local x_description=""
    ___x_cmd_skill___data_get_index_record_ "$skillid" || return $?

    [ -d "$datadir" ] || {
        case "$x_url" in
            x-cmd-skill-data:*)
                if ___x_cmd websrc is cn; then
                    x_url="https://codeberg.org/x-cmd/skill/releases/download/latest/${x_url##*/}.zip"
                else
                    x_url="https://github.com/x-cmd/skill/releases/latest/download/${x_url##*/}.zip"
                fi
                ;;
        esac
        ___x_cmd_skill___data_install_from_web "$x_url" "$skillid" "$x_reference" "$x_license" "$x_author" || {
            skill:error --datadir "$datadir" "Not found skill[$skillid]"
            return 1
        }
    }

    local target="$dir/$x_name"
    ___x_cmd rmrf "$target"
    ___x_cmd ensurefp "$target"
    ___x_cmd_cmds cp -rf "$datadir" "$target"

    skill:info "Successfully activated skill[$skillid] -> $target"
}


___x_cmd_skill_add___fromgithub(){
    local target_dir="$1"
    local url="$2"
    local skills="$3"
    local nocache="$4"

    local owner; local repo
    owner="${url#https://github.com/}"
    owner="${owner%.git}"
    repo="${owner#*/}"
    owner="${owner%/*}"
    [ -n "$owner" ] && [ -n "$repo" ] || {
        N=skill M="Invalid GitHub URL: $url" log:ret:64
    }

    local cache_dir="$___X_CMD_SKILL_DATA_DIR/github/${owner}/${repo}"
    if [ ! -d "$cache_dir" ] || [ "$nocache" = 1 ] ; then
        ___x_cmd_skill___data_fromgithub "$owner" "$repo" "$cache_dir" || return $?
    fi

    local all_skills_data; all_skills_data="$(___x_cmd_cmds find "$cache_dir" -mindepth 1 -type f -name 'SKILL.md' 2>/dev/null)"
    [ -n "$all_skills_data" ] || N=skill M="No SKILL.md found in ${owner}/${repo}" log:ret:1

    local skill_name; local skill_data;
    if [ -n "$skills" ];then
        while read -r skill_name; do
            skill_data="$( printf "%s" "$all_skills_data" | ___x_cmd_cmds grep "/$skill_name/" 2>/dev/null)"
            [ -n "$skill_data" ] || {
                skill:error --run "x skill lr --github $url" "No $skill_name found in ${owner}/${repo}"
                return 1
            }
            ___x_cmd_skill_add___fromgithub_copy "$skill_data" "$target_dir"
        done <<A
$skills
A
    else
        while read -r skill_data; do
            ___x_cmd_skill_add___fromgithub_copy "$skill_data" "$target_dir"
        done <<A
$all_skills_data
A
    fi
    skill:info "Successfully added skill from GitHub[${owner}/${repo}] -> $target_dir"
}

___x_cmd_skill_add___fromgithub_copy(){
    local src="$1"; src="${src%/SKILL.md}"
    local dst="$2"
    local name="${src##*/}"
    ___x_cmd ensurefp "$dst/$name"
    ___x_cmd rmrf "$dst/$name"
    ___x_cmd_cmds cp -rf "$src" "$dst/$name" || {
        skill:error "Failed to copy skill[$name] to $dst"
        return 1
    }
    skill:info "Successfully activated skill[$name] -> $dst/$name"
}

___x_cmd_skill_add___fromclawhub(){
    local target_dir="$1"
    local name="$2"
    local nocache="$3"

    name="${name#*clawhub/}"
    target_dir="$target_dir/$name"
    local cache_dir="$___X_CMD_SKILL_DATA_DIR/clawhub/${name}"
    if [ ! -d "$cache_dir" ] || [ "$nocache" = 1 ] ; then
        local tmptar="$___X_CMD_ROOT_TMP/skill/clawhub/${name}.zip"
        ___x_cmd ensurefp "$tmptar"                || return $?
        ___x_cmd clawhub download "${name}" -o "$tmptar" || {
            ___x_cmd rmrf "$tmptar"
            return 1
        }

        ___x_cmd rmrf "$cache_dir"                    || return $?
        ___x_cmd mkdirp "$cache_dir"                  || return $?
        ___X_CMD_ZUZ_QUIET=1 ___x_cmd uz "$tmptar" "$cache_dir"
    fi

    [ -f "$cache_dir/SKILL.md" ] || N=skill M="No SKILL.md found in [$cache_dir]" log:ret:1

    ___x_cmd ensurefp "$target_dir"
    ___x_cmd rmrf "$target_dir"
    ___x_cmd_cmds cp -rf "$cache_dir" "$target_dir" || {
        skill:error "Failed to copy skill[$name] to $target_dir"
        return 1
    }
    skill:info "Successfully activated skill[$name] -> $target_dir"
}

___x_cmd_skill_add___fromxmod(){
    local target_dir="$1"
    local name="$2"

    name="${name#*x-mod/}"
    target_dir="$target_dir/$name"

    ___x_cmd ensurefp "$target_dir/SKILL.md"
    ___x_cmd rmrf "$target_dir/SKILL.md"
    ___x_cmd_skill_lr___xcmd___generate_modskill "$name" > "$target_dir/SKILL.md" || {
        skill:error "Failed to copy skill[$name] to $target_dir"
        return 1
    }
    skill:info "Successfully activated skill[$name] -> $target_dir"

}
