#!/bin/bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="${KAMIWAZA_ROOT:-$(cd "${SCRIPT_DIR}/.." && pwd)}"

hash_file() {
    local target="$1"
    local canonical="$target"

    if [[ -z "$target" ]]; then
        echo "unknown"
        return 1
    fi

    if command -v python3 >/dev/null 2>&1; then
        if ! canonical=$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$target" 2>/dev/null); then
            echo "unknown"
            return 1
        fi
    elif command -v realpath >/dev/null 2>&1; then
        if ! canonical=$(realpath "$target" 2>/dev/null); then
            echo "unknown"
            return 1
        fi
    elif command -v readlink >/dev/null 2>&1; then
        canonical=$(readlink -f "$target" 2>/dev/null || printf '%s' "$target")
    fi

    if [[ ! -f "$canonical" ]]; then
        echo "missing"
        return 0
    fi

    case "$canonical" in
        "${PROJECT_DIR}"/*) ;;
        *) echo "unknown"; return 1 ;;
    esac

    if command -v shasum >/dev/null 2>&1; then
        shasum -a 256 "$canonical" | awk '{print $1}'
        return 0
    fi

    if command -v sha256sum >/dev/null 2>&1; then
        sha256sum "$canonical" | awk '{print $1}'
        return 0
    fi

    echo "unknown"
    return 1
}

pip_bootstrap_env() {
    local host_python="${PYTHON3_BIN:-}"

    if [[ -z "$host_python" ]]; then
        if command -v python3 >/dev/null 2>&1; then
            host_python="$(command -v python3)"
        elif command -v python >/dev/null 2>&1; then
            host_python="$(command -v python)"
        fi
    fi

    if [[ -z "$host_python" ]]; then
        echo "kw_py: no system python available for pip fallback bootstrap" >&2
        return 1
    fi

    if [[ ! -d "${PROJECT_DIR}/.venv" ]]; then
        "$host_python" -m venv "${PROJECT_DIR}/.venv"
    fi
    "$host_python" -m venv --upgrade-deps "${PROJECT_DIR}/.venv"
    local venv_python="${PROJECT_DIR}/.venv/bin/python"
    if [[ ! -x "$venv_python" ]]; then
        echo "kw_py: unable to locate managed interpreter at ${venv_python}" >&2
        return 1
    fi

    "$venv_python" -m ensurepip --upgrade >/dev/null 2>&1 || true

    "$venv_python" -m pip install --upgrade pip setuptools wheel >&2

    local requirements_file="${PROJECT_DIR}/requirements.txt"
    if [[ ! -f "$requirements_file" ]]; then
        echo "kw_py: requirements.txt not found; cannot bootstrap dependencies" >&2
        return 1
    fi

    "$venv_python" -m pip install -r "$requirements_file" >&2
}

verify_managed_env_ready() {
    local managed_python="${PROJECT_DIR}/.venv/bin/python"
    if [[ ! -x "$managed_python" ]]; then
        return 1
    fi

    "$managed_python" - <<'PY' >/dev/null 2>&1
import importlib.util
import sys
required = ("pydantic", "fastapi")
missing = [m for m in required if importlib.util.find_spec(m) is None]
sys.exit(0 if not missing else 1)
PY
}

bootstrap_uv_env_if_needed() {
    if [[ "${KW_PY_NO_SYNC:-}" != "1" ]]; then
        return 0
    fi

    local marker_dir="${PROJECT_DIR}/.kw"
    local marker_file="${marker_dir}/kw_py.ready"
    local pip_mode_file="${marker_dir}/kw_py.force_pip"
    local managed_python="${PROJECT_DIR}/.venv/bin/python"
    local needs_sync=0
    local current_py_hash current_lock_hash
    local KW_PY_MARKER_PY_HASH=""
    local KW_PY_MARKER_LOCK_HASH=""
    local pip_only="false"

    current_py_hash=$(hash_file "${PROJECT_DIR}/pyproject.toml")
    current_lock_hash=$(hash_file "${PROJECT_DIR}/uv.lock")
    if [[ -f "$pip_mode_file" ]]; then
        pip_only="true"
    fi

    if [[ ! -x "$managed_python" ]]; then
        needs_sync=1
    elif [[ ! -f "$marker_file" ]]; then
        needs_sync=1
    else
        # shellcheck disable=SC1090
        source "$marker_file" >/dev/null 2>&1 || true
        if [[ "$KW_PY_MARKER_PY_HASH" != "$current_py_hash" ]] || [[ "$KW_PY_MARKER_LOCK_HASH" != "$current_lock_hash" ]]; then
            needs_sync=1
        fi
    fi

    if [[ "$needs_sync" -ne 1 ]]; then
        if verify_managed_env_ready; then
            return 0
        fi
        needs_sync=1
    fi

    mkdir -p "$marker_dir"
    echo "kw_py: KW_PY_NO_SYNC=1 but dependencies are missing/stale; bootstrapping environment" >&2
    if [[ "$pip_only" != "true" ]]; then
        if [[ -x "${PROJECT_DIR}/uv_sync.sh" ]]; then
            (
                cd "${PROJECT_DIR}"
                KW_PY_NO_SYNC=0 KW_UV_NO_DEFAULT=1 KW_UV_GROUPS= ./uv_sync.sh >&2
            ) || echo "kw_py: uv_sync.sh failed; attempting pip-based fallback install" >&2
        else
            uv --project "$PROJECT_DIR" sync || echo "kw_py: 'uv sync' failed; attempting pip-based fallback install" >&2
        fi
    else
        echo "kw_py: uv bootstrap disabled (pip-only mode)" >&2
    fi
    
    if ! verify_managed_env_ready; then
        echo "kw_py: managed environment still missing core dependencies after uv sync; attempting pip fallback" >&2
        if ! pip_bootstrap_env; then
            echo "kw_py: unable to bootstrap Python environment via uv or pip" >&2
            return 1
        fi
        touch "$pip_mode_file"
        if ! verify_managed_env_ready; then
            echo "kw_py: managed environment still missing core dependencies after bootstrap" >&2
            return 1
        fi
    fi

    local final_py_hash final_lock_hash
    final_py_hash=$(hash_file "${PROJECT_DIR}/pyproject.toml")
    final_lock_hash=$(hash_file "${PROJECT_DIR}/uv.lock")
    {
        echo "KW_PY_MARKER_PY_HASH=\"$final_py_hash\""
        echo "KW_PY_MARKER_LOCK_HASH=\"$final_lock_hash\""
        echo "KW_PY_MARKER_TIMESTAMP=\"$(date -u +%s)\""
    } >"$marker_file"

    if [[ "$pip_only" == "true" && ! -f "$pip_mode_file" ]]; then
        touch "$pip_mode_file"
    fi
}

if command -v uv >/dev/null 2>&1; then
    bootstrap_uv_env_if_needed
    UV_CMD=(uv --project "$PROJECT_DIR" run)
    if [[ "${KW_PY_NO_SYNC:-}" == "1" ]]; then
        UV_CMD+=("--frozen")
    fi
    UV_CMD+=("python")
    exec "${UV_CMD[@]}" "$@"
fi

echo "kw_py: uv not found on PATH; falling back to system python" >&2
if command -v python3 >/dev/null 2>&1; then
    exec python3 "$@"
fi
exec python "$@"
