#!/usr/bin/env bash
# Shared SessionStart context helpers for skillwiki hook entrypoints.

read_config_value() {
    local file="$1"
    local key="$2"
    local line

    line=$(grep -E "^[[:space:]]*${key}:" "$file" 2>/dev/null | head -n 1 || true)
    [[ -n "$line" ]] || return 0

    printf '%s' "$line" \
        | sed -E "s/^[[:space:]]*${key}:[[:space:]]*//; s/[[:space:]]+#.*$//; s/[[:space:]]+$//; s/^['\"]//; s/['\"]$//"
}

find_dev_loop_config() {
    local dir="${PWD}"

    while [[ -n "$dir" && "$dir" != "/" ]]; do
        if [[ -f "${dir}/.claude/dev-loop.config.md" ]]; then
            printf '%s' "${dir}/.claude/dev-loop.config.md"
            return 0
        fi
        dir=$(dirname "$dir")
    done

    return 0
}

build_project_prd_context() {
    local config_path
    config_path=$(find_dev_loop_config)
    [[ -n "$config_path" ]] || return 0

    local prd_layer
    local prd_pipeline
    prd_layer=$(read_config_value "$config_path" "prd_layer")
    prd_pipeline=$(read_config_value "$config_path" "prd_pipeline")

    [[ -n "$prd_layer" || -n "$prd_pipeline" ]] || return 0

    prd_layer="${prd_layer:-unspecified}"
    prd_pipeline="${prd_pipeline:-unspecified}"

    cat <<EOF
## Project PRD Mode

Detected \`.claude/dev-loop.config.md\` for this workspace:
- \`prd_layer\`: \`${prd_layer}\`
- \`prd_pipeline\`: \`${prd_pipeline}\`

Use this detected PRD mode as the source of truth. Route generated spec/plan artifacts through \`proj-work\`, and do not write them under \`docs/superpowers/\`. If \`prd_layer\` is \`superpowers\` or \`tdd\`, ensure \`EnterPlanMode\` is gated with \`wiki-gate-plan-mode\`. Do not assume \`superpowers/full\` unless the config says so.
EOF
}

read_dotenv_key() {
    local file="$1"
    local key="$2"
    local line

    [[ -f "$file" ]] || return 0
    line=$(grep -E "^[[:space:]]*${key}=" "$file" 2>/dev/null | head -n 1 || true)
    [[ -n "$line" ]] || return 0

    printf '%s' "$line" \
        | sed -E "s/^[[:space:]]*${key}=//; s/[[:space:]]+#.*$//; s/[[:space:]]+$//; s/^['\"]//; s/['\"]$//"
}

resolve_vault_path_for_session() {
    if [[ -n "${WIKI_PATH:-}" ]]; then
        printf '%s' "$WIKI_PATH"
        return 0
    fi

    local project_env="${PWD}/skillwiki/.env"
    local project_path
    project_path=$(read_dotenv_key "$project_env" "WIKI_PATH")
    if [[ -n "$project_path" ]]; then
        printf '%s' "$project_path"
        return 0
    fi

    local global_path
    global_path=$(read_dotenv_key "${HOME:-}/.skillwiki/.env" "WIKI_PATH")
    if [[ -n "$global_path" ]]; then
        printf '%s' "$global_path"
        return 0
    fi

    if command -v skillwiki >/dev/null 2>&1; then
        skillwiki path 2>/dev/null | sed -n 's/^{"ok":true,"data":{"path":"\([^"]*\)".*$/\1/p' | head -n 1
    fi
}

file_mtime_epoch() {
    local file="$1"

    stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null || printf '0'
}

strip_frontmatter_for_session() {
    local file="$1"

    awk '
        NR == 1 && $0 == "---" { in_fm = 1; next }
        in_fm && $0 == "---" { in_fm = 0; next }
        !in_fm { print }
    ' "$file" 2>/dev/null
}

read_session_brief_candidate() {
    local vault="$1"
    local file="$2"
    local label="$3"
    local max_age_hours="$4"
    local strip_frontmatter="${5:-false}"

    [[ -f "$file" ]] || return 1

    local now
    local mtime
    local age_seconds
    local age_hours
    now=$(date +%s)
    mtime=$(file_mtime_epoch "$file")
    [[ "$mtime" =~ ^[0-9]+$ ]] || mtime=0
    age_seconds=$((now - mtime))
    if (( age_seconds < 0 )); then age_seconds=0; fi
    age_hours=$((age_seconds / 3600))

    if (( age_hours > max_age_hours )); then
        return 1
    fi

    local freshness="fresh"
    if (( age_hours >= 24 )); then
        freshness="stale"
    fi

    printf '## Dynamic Session Memory\n\n'
    printf '_Source: %s; Session brief age: %s (%sh)._ \n\n' "$label" "$freshness" "$age_hours"

    if [[ "$strip_frontmatter" == "true" ]]; then
        strip_frontmatter_for_session "$file"
    else
        cat "$file" 2>/dev/null
    fi
}

compute_session_brief_readonly() {
    local vault="$1"

    command -v skillwiki >/dev/null 2>&1 || return 1
    skillwiki session-brief "$vault" --project auto --human 2>/dev/null || return 1
}

build_dynamic_session_memory() {
    local vault
    vault=$(resolve_vault_path_for_session)
    [[ -n "$vault" && -d "$vault" ]] || return 0

    local cache_file="${vault}/.skillwiki/session-brief.md"
    local committed_file="${vault}/meta/latest-session-brief.md"
    local brief

    if brief=$(read_session_brief_candidate "$vault" "$cache_file" ".skillwiki/session-brief.md" 72 false); then
        printf '%s' "$brief"
        return 0
    fi

    if brief=$(read_session_brief_candidate "$vault" "$committed_file" "meta/latest-session-brief.md" 72 true); then
        printf '%s' "$brief"
        return 0
    fi

    if brief=$(compute_session_brief_readonly "$vault"); then
        printf '## Dynamic Session Memory\n\n'
        printf '_Source: read-only `skillwiki session-brief --project auto --human` fallback._\n\n'
        printf '%s' "$brief"
        return 0
    fi

    return 0
}

build_runtime_host_context() {
    local vault
    vault=$(resolve_vault_path_for_session)

    if command -v skillwiki >/dev/null 2>&1; then
        local context
        if [[ -n "$vault" && -d "$vault" ]]; then
            context=$(skillwiki --human fleet context "$vault" 2>/dev/null || true)
        else
            context=$(skillwiki --human fleet context 2>/dev/null || true)
        fi
        if [[ "$context" == *"## Runtime Host Context"* ]]; then
            printf '%s' "$context"
            return 0
        fi
    fi

    local os_hostname
    local current_user
    os_hostname=$(hostname -s 2>/dev/null || hostname 2>/dev/null || printf '')
    current_user=$(id -un 2>/dev/null || printf '%s' "${USER:-}")

    cat <<EOF
## Runtime Host Context

- Current machine: unknown
- OS hostname: \`${os_hostname:-unknown}\`
- User: \`${current_user:-unknown}\`
- Workspace: \`${PWD}\`
- Vault: \`${vault:-unknown}\`
- Fleet role: unknown
- Self SSH aliases known in fleet: unknown
- Declared outbound SSH from this source: unknown
- Guidance: host identity is unresolved; do not assume local vs remote role. Inspect runtime or ask before SSH/deploy/sync work.
EOF
}

escape_for_json() {
    local s="$1"
    s="${s//\\/\\\\}"
    s="${s//\"/\\\"}"
    s="${s//$'\n'/\\n}"
    s="${s//$'\r'/\\r}"
    s="${s//$'\t'/\\t}"
    printf '%s' "$s"
}

read_skill_content() {
    local skill_path="$1"
    cat "$skill_path" 2>/dev/null || echo "Error reading using-skillwiki skill"
}

resolve_skill_path() {
    local plugin_root="$1"
    local skill_name="$2"
    local candidate

    for candidate in \
        "${plugin_root}/${skill_name}/SKILL.md" \
        "${plugin_root}/skills/${skill_name}/SKILL.md"; do
        if [[ -f "$candidate" ]]; then
            printf '%s' "$candidate"
            return 0
        fi
    done

    printf '%s' "${plugin_root}/${skill_name}/SKILL.md"
}

build_skillwiki_session_context() {
    local skill_content="$1"
    local project_prd_context
    local dynamic_session_memory
    local runtime_host_context
    local session_context

    project_prd_context=$(build_project_prd_context)
    dynamic_session_memory=$(build_dynamic_session_memory)
    runtime_host_context=$(build_runtime_host_context)

    session_context=$'### Skillwiki Activation\n\nSkillwiki is active for this workspace. Below are the capability guidelines for local reference:'
    if [[ -n "$runtime_host_context" ]]; then
        session_context+=$'\n\n'
        session_context+="$runtime_host_context"
    fi
    if [[ -n "$dynamic_session_memory" ]]; then
        session_context+=$'\n\n'
        session_context+="$dynamic_session_memory"
    fi
    if [[ -n "$project_prd_context" ]]; then
        session_context+=$'\n\n'
        session_context+="$project_prd_context"
    fi
    session_context+=$'\n\n'
    session_context+="$skill_content"

    printf '%s' "$session_context"
}

print_session_start_json() {
    local session_context
    session_context=$(escape_for_json "$1")

    # Uses printf instead of heredoc to work around bash 5.3+ heredoc hang.
    printf '{\n  "hookSpecificOutput": {\n    "hookEventName": "SessionStart",\n    "additionalContext": "%s"\n  }\n}\n' "$session_context"
}
