#!/bin/sh
set -eu

usage() {
    cat <<'EOF'
usage: ink-skills list
       ink-skills install [--user | --project DIR] [SKILL ...]

Install Ink skills from this checkout as symlinks.

Commands:
  list             List available skill names and source paths as TSV.
  install          Link named skills; with no names, link every skill.

Targets:
  --user           $INK_SKILLS_HOME or $HOME/.ink/skills (default)
  --project DIR    DIR/.ink/skills

Output:
  TSV with SKILL, TARGET, and ACTION columns.

Exit status:
  0 success; 2 usage error; 3 target collision or invalid skill.

Examples:
  ink-skills list
  ink-skills install ink-cli configure-ink-agent
  ink-skills install --project . create-ink-agent-cli-tool
EOF
}

die() {
    printf '%s\n' "ink-skills: $*" >&2
    exit 3
}

script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
repo_dir=$(CDPATH= cd -- "$script_dir/.." && pwd -P)
skills_dir=$repo_dir/skills

list_skills() {
    printf 'SKILL\tSOURCE\n'
    for path in "$skills_dir"/*; do
        [ -d "$path" ] || continue
        [ -f "$path/SKILL.md" ] || continue
        printf '%s\t%s\n' "$(basename -- "$path")" "$path"
    done
}

[ "$#" -gt 0 ] || {
    usage >&2
    exit 2
}

command=$1
shift
case $command in
    -h|--help|help)
        usage
        exit 0
        ;;
    list)
        [ "$#" -eq 0 ] || {
            usage >&2
            exit 2
        }
        list_skills
        exit 0
        ;;
    install) ;;
    *)
        usage >&2
        exit 2
        ;;
esac

target_mode=user
target_arg=
while [ "$#" -gt 0 ]; do
    case $1 in
        --user)
            target_mode=user
            shift
            ;;
        --project)
            [ "$#" -ge 2 ] || {
                usage >&2
                exit 2
            }
            target_mode=project
            target_arg=$2
            shift 2
            ;;
        --)
            shift
            break
            ;;
        -*)
            usage >&2
            exit 2
            ;;
        *) break ;;
    esac
done

case $target_mode in
    user)
        if [ -n "${INK_SKILLS_HOME:-}" ]; then
            target=$INK_SKILLS_HOME
        else
            [ -n "${HOME:-}" ] || die 'HOME is unset; set HOME or INK_SKILLS_HOME'
            target=$HOME/.ink/skills
        fi
        ;;
    project)
        project=$(CDPATH= cd -- "$target_arg" 2>/dev/null && pwd -P) || die "project directory not found: $target_arg"
        target=$project/.ink/skills
        ;;
esac

mkdir -p -- "$target"

if [ "$#" -eq 0 ]; then
    set --
    for path in "$skills_dir"/*; do
        [ -d "$path" ] || continue
        [ -f "$path/SKILL.md" ] || continue
        set -- "$@" "$(basename -- "$path")"
    done
fi

printf 'SKILL\tTARGET\tACTION\n'
for skill do
    case $skill in
        ''|.*|*/*) die "invalid skill name: $skill" ;;
    esac
    source=$skills_dir/$skill
    [ -d "$source" ] && [ -f "$source/SKILL.md" ] || die "unknown skill: $skill"
    destination=$target/$skill
    if [ -L "$destination" ]; then
        linked=$(readlink "$destination")
        [ "$linked" = "$source" ] || die "refusing foreign symlink: $destination -> $linked"
        action=unchanged
    elif [ -e "$destination" ]; then
        die "refusing existing path: $destination"
    else
        ln -s -- "$source" "$destination"
        action=linked
    fi
    printf '%s\t%s\t%s\n' "$skill" "$destination" "$action"
done
