#!/usr/bin/env bash

if [ -n "${HALLUCINATE_HOOK_LOADED:-}" ]; then
  return 0 2>/dev/null || exit 0
fi
HALLUCINATE_HOOK_LOADED=1

: "${HALLUCINATE_STREAM_FILE:=/tmp/hallucinate_stream.json}"

HALLUCINATE_SESSION_ID="${HALLUCINATE_SESSION_ID:-$$}"
HALLUCINATE_STATE_FILE="/tmp/hallucinate_state_${HALLUCINATE_SESSION_ID}.target"
: > "$HALLUCINATE_STATE_FILE"

exec {HALLUCINATE_ORIG_STDERR_FD}>&2

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

_hallucinate_path_within_workspace() {
  if [ -z "${HALLUCINATE_WORKSPACE_ROOT:-}" ]; then
    return 0
  fi
  case "$PWD/" in
    "$HALLUCINATE_WORKSPACE_ROOT"/|"$HALLUCINATE_WORKSPACE_ROOT"/*)
      return 0
      ;;
    *)
      return 1
      ;;
  esac
}

_hallucinate_log_event() {
  local exit_code="$1"
  local cmd="$2"
  local stderr_text="$3"
  local ts
  ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
  local actor="${HALLUCINATE_ACTOR:-human}"

  _hallucinate_path_within_workspace || return 0

  mkdir -p "$(dirname "$HALLUCINATE_STREAM_FILE")"

  local cmd_esc stderr_esc cwd_esc workspace_esc
  cmd_esc="$(_hallucinate_json_escape "$cmd")"
  stderr_esc="$(_hallucinate_json_escape "$stderr_text")"
  cwd_esc="$(_hallucinate_json_escape "$PWD")"
  workspace_esc="$(_hallucinate_json_escape "${HALLUCINATE_WORKSPACE_ROOT:-}")"

  printf '{"ts":"%s","shell":"%s","actor":"%s","session":%s,"pid":%s,"cwd":"%s","workspace_root":"%s","exit_code":%s,"command":"%s","stderr":"%s"}\n' \
    "$ts" "${ZSH_VERSION:+zsh}${BASH_VERSION:+bash}" "$actor" "$HALLUCINATE_SESSION_ID" "$$" "$cwd_esc" "$workspace_esc" "$exit_code" "$cmd_esc" "$stderr_esc" \
    >> "$HALLUCINATE_STREAM_FILE"
}

_hallucinate_stderr_router() {
  local line target
  while IFS= read -r line || [ -n "$line" ]; do
    printf '%s\n' "$line" >&"$HALLUCINATE_ORIG_STDERR_FD"
    target="$(cat "$HALLUCINATE_STATE_FILE" 2>/dev/null)"
    if [ -n "$target" ]; then
      printf '%s\n' "$line" >> "$target"
    fi
  done
}

exec 2> >(_hallucinate_stderr_router)

if [ -n "${ZSH_VERSION:-}" ]; then
  autoload -Uz add-zsh-hook 2>/dev/null || true

  _hallucinate_zsh_preexec() {
    HALLUCINATE_LAST_CMD="$1"
    HALLUCINATE_ERR_FILE="/tmp/hallucinate_stderr_${HALLUCINATE_SESSION_ID}.log"
    : > "$HALLUCINATE_ERR_FILE"
    printf '%s' "$HALLUCINATE_ERR_FILE" > "$HALLUCINATE_STATE_FILE"
  }

  _hallucinate_zsh_precmd() {
    local exit_code="$?"
    local stderr_text=""

    printf '' > "$HALLUCINATE_STATE_FILE"
    if [ -n "${HALLUCINATE_ERR_FILE:-}" ] && [ -f "$HALLUCINATE_ERR_FILE" ]; then
      stderr_text="$(cat "$HALLUCINATE_ERR_FILE")"
      rm -f "$HALLUCINATE_ERR_FILE"
    fi

    if [ -n "${HALLUCINATE_LAST_CMD:-}" ]; then
      _hallucinate_log_event "$exit_code" "$HALLUCINATE_LAST_CMD" "$stderr_text"
      HALLUCINATE_LAST_CMD=""
    fi
  }

  add-zsh-hook preexec _hallucinate_zsh_preexec
  add-zsh-hook precmd _hallucinate_zsh_precmd
fi

if [ -n "${BASH_VERSION:-}" ]; then
  HALLUCINATE_BASH_IN_CMD=0
  HALLUCINATE_BASH_IN_PROMPT=0

  _hallucinate_bash_preexec() {
    [ "${HALLUCINATE_BASH_IN_PROMPT:-0}" -eq 1 ] && return 0

    if [ "${HALLUCINATE_BASH_IN_CMD:-0}" -eq 0 ]; then
      HALLUCINATE_BASH_IN_CMD=1
      HALLUCINATE_LAST_CMD="$(history 1 | sed 's/^ *[0-9][0-9]* *//')"
      HALLUCINATE_ERR_FILE="/tmp/hallucinate_stderr_${HALLUCINATE_SESSION_ID}.log"
      : > "$HALLUCINATE_ERR_FILE"
      printf '%s' "$HALLUCINATE_ERR_FILE" > "$HALLUCINATE_STATE_FILE"
    fi
  }

  _hallucinate_bash_precmd() {
    local exit_code="$?"
    local stderr_text=""

    HALLUCINATE_BASH_IN_PROMPT=1

    if [ "${HALLUCINATE_BASH_IN_CMD:-0}" -eq 1 ]; then
      printf '' > "$HALLUCINATE_STATE_FILE"
      if [ -n "${HALLUCINATE_ERR_FILE:-}" ] && [ -f "$HALLUCINATE_ERR_FILE" ]; then
        stderr_text="$(cat "$HALLUCINATE_ERR_FILE")"
        rm -f "$HALLUCINATE_ERR_FILE"
      fi
      _hallucinate_log_event "$exit_code" "${HALLUCINATE_LAST_CMD:-}" "$stderr_text"
      HALLUCINATE_BASH_IN_CMD=0
      HALLUCINATE_LAST_CMD=""
    fi

    HALLUCINATE_BASH_IN_PROMPT=0
    return "$exit_code"
  }

  trap '_hallucinate_bash_preexec' DEBUG

  if [ -n "${PROMPT_COMMAND:-}" ]; then
    PROMPT_COMMAND="_hallucinate_bash_precmd; ${PROMPT_COMMAND}"
  else
    PROMPT_COMMAND="_hallucinate_bash_precmd"
  fi
fi
