#!/bin/sh

set -eu

BASE_URL="${TSC_GIT_HOOK_BASE_URL:-https://hook.tsc-security.tools}"
INSTALL_DIR="${TSC_GIT_HOOK_INSTALL_DIR:-$HOME/.local/bin}"
TMP_DIR="$(mktemp -d)"

cleanup() {
  rm -rf "$TMP_DIR"
}

trap cleanup EXIT INT TERM

log_step() {
  printf '==> %s\n' "$1"
}

log_info() {
  printf '    %s\n' "$1"
}

fail() {
  printf 'Error %s\n' "$1" >&2
  exit 1
}

require_command() {
  if ! command -v "$1" >/dev/null 2>&1; then
    fail "Missing required command: $1"
  fi
}

detect_os() {
  case "$(uname -s)" in
    Linux)
      printf 'linux'
      ;;
    Darwin)
      printf 'osx'
      ;;
    *)
      fail "Unsupported operating system: $(uname -s)"
      ;;
  esac
}

detect_arch() {
  case "$(uname -m)" in
    x86_64|amd64)
      printf 'x64'
      ;;
    arm64|aarch64)
      printf 'arm64'
      ;;
    *)
      fail "Unsupported CPU architecture: $(uname -m)"
      ;;
  esac
}

append_path_if_needed() {
  path_entry="export PATH=\"$INSTALL_DIR:\$PATH\""
  for candidate in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do
    if [ -f "$candidate" ] || [ ! -e "$candidate" ]; then
      if [ -f "$candidate" ] && grep -F "$INSTALL_DIR" "$candidate" >/dev/null 2>&1; then
        return 0
      fi

      printf '\n%s\n' "$path_entry" >> "$candidate"
      log_info "Added $INSTALL_DIR to PATH in $candidate"
      return 0
    fi
  done
}

extract_zip() {
  archive_path="$1"
  destination="$2"

  if command -v unzip >/dev/null 2>&1; then
    unzip -qq "$archive_path" -d "$destination"
    return 0
  fi

  python3 - "$archive_path" "$destination" <<'PY'
import pathlib
import sys
import zipfile

archive = pathlib.Path(sys.argv[1])
destination = pathlib.Path(sys.argv[2])

with zipfile.ZipFile(archive) as bundle:
    bundle.extractall(destination)
PY
}

require_command curl
require_command python3

TARGET_OS="$(detect_os)"
TARGET_ARCH="$(detect_arch)"
MANIFEST_URL="$BASE_URL/releases/releases.json"
MANIFEST_PATH="$TMP_DIR/releases.json"

log_step "Fetching release manifest"
curl -fsSL "$MANIFEST_URL" -o "$MANIFEST_PATH"

ARTIFACT_JSON="$(python3 - "$MANIFEST_PATH" "$TARGET_OS" "$TARGET_ARCH" <<'PY'
import json
import pathlib
import sys

manifest_path = pathlib.Path(sys.argv[1])
target_os = sys.argv[2]
target_arch = sys.argv[3]

manifest = json.loads(manifest_path.read_text(encoding="utf-8"))

for release in manifest.get("releases", []):
    for artifact in release.get("artifacts", []):
        if artifact.get("os") == target_os and artifact.get("arch") == target_arch:
            print(json.dumps({"version": release["version"], "artifact": artifact}))
            raise SystemExit(0)

raise SystemExit("No compatible release was found for this platform.")
PY
)" || fail "Could not resolve a compatible release from $MANIFEST_URL"

VERSION="$(printf '%s' "$ARTIFACT_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')"
FILENAME="$(printf '%s' "$ARTIFACT_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["artifact"]["filename"])')"
SHA256_EXPECTED="$(printf '%s' "$ARTIFACT_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["artifact"]["sha256"])')"
ARTIFACT_URL="$BASE_URL/releases/$FILENAME"
ARCHIVE_PATH="$TMP_DIR/$FILENAME"
EXTRACT_DIR="$TMP_DIR/extracted"

mkdir -p "$EXTRACT_DIR" "$INSTALL_DIR"

log_step "Downloading tsc-git-hook $VERSION"
curl -fsSL "$ARTIFACT_URL" -o "$ARCHIVE_PATH"

ACTUAL_SHA256="$(python3 - "$ARCHIVE_PATH" <<'PY'
import hashlib
import pathlib
import sys

path = pathlib.Path(sys.argv[1])
print(hashlib.sha256(path.read_bytes()).hexdigest())
PY
)"

[ "$ACTUAL_SHA256" = "$SHA256_EXPECTED" ] || fail "Checksum validation failed for $FILENAME"

log_step "Installing into $INSTALL_DIR"
extract_zip "$ARCHIVE_PATH" "$EXTRACT_DIR"
install -m 0755 "$EXTRACT_DIR/tsc-git-hook" "$INSTALL_DIR/tsc-git-hook"

append_path_if_needed
export PATH="$INSTALL_DIR:$PATH"

log_step "Installed tsc-git-hook $VERSION"
log_info "Run 'tsc-git-hook --help' to get started."
