#!/usr/bin/env bash
# Read-only curl wrapper for the Zoho Mail API.
#
# Usage:
#   zoho-curl.sh <path>                  # e.g. zoho-curl.sh /accounts
#   zoho-curl.sh -i <path>               # include curl's -i (response headers)
#   zoho-curl.sh -o file.json <path>     # write body to file
#
# Reads credentials from ../../dolibarr/.env (the shared canonical file).
# Required vars:
#   ZOHO_CLIENT_ID, ZOHO_CLIENT_SECRET, ZOHO_REFRESH_TOKEN, ZOHO_DC
#
# Token strategy: each invocation refreshes a short-lived access_token from
# the refresh_token (Zoho access_tokens live 1h; the cost of refreshing on
# every call is ~150 ms and avoids state on disk). On 401 from the mail API
# we re-refresh once and retry (covers refresh-token rotation cases).
#
# Exits non-zero on HTTP >= 400 and writes body to stdout + a short message
# to stderr — same shape as dol-curl.sh / bank-curl.sh.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/../../dolibarr/.env"

if [[ ! -f "${ENV_FILE}" ]]; then
  echo "zoho-curl.sh: missing ${ENV_FILE}" >&2
  echo "  Required vars: ZOHO_CLIENT_ID, ZOHO_CLIENT_SECRET, ZOHO_REFRESH_TOKEN, ZOHO_DC." >&2
  echo "  See arcodange-email-ingest/SKILL.md for the OAuth setup." >&2
  exit 2
fi
set -a; source "${ENV_FILE}"; set +a

: "${ZOHO_CLIENT_ID:?zoho-curl.sh: ZOHO_CLIENT_ID not set in .env}"
: "${ZOHO_CLIENT_SECRET:?zoho-curl.sh: ZOHO_CLIENT_SECRET not set in .env}"
: "${ZOHO_REFRESH_TOKEN:?zoho-curl.sh: ZOHO_REFRESH_TOKEN not set in .env}"
: "${ZOHO_DC:=eu}"

ACCOUNTS_BASE="https://accounts.zoho.${ZOHO_DC}"
MAIL_BASE="https://mail.zoho.${ZOHO_DC}/api"

# Parse pass-through curl args (everything before the last positional)
PASSTHRU=()
while [[ $# -gt 1 ]]; do
  PASSTHRU+=("$1"); shift
done
if [[ $# -lt 1 ]]; then
  echo "zoho-curl.sh: missing API path. Example: zoho-curl.sh /accounts" >&2
  exit 2
fi
API_PATH="$1"

# Cache access_token in tmpfs to avoid hitting OAuth rate limits on every
# zoho-curl invocation. Zoho access_tokens live 1h; we refresh after 50 min.
CACHE_FILE="${TMPDIR:-/tmp}/zoho-access-$(whoami)"
CACHE_TTL_SECONDS=$((50 * 60))

get_access_token() {
  if [[ -f "${CACHE_FILE}" ]]; then
    local age
    age=$(( $(date +%s) - $(stat -f %m "${CACHE_FILE}" 2>/dev/null || stat -c %Y "${CACHE_FILE}") ))
    if [[ ${age} -lt ${CACHE_TTL_SECONDS} ]]; then
      cat "${CACHE_FILE}"
      return 0
    fi
  fi
  local token
  if ! token=$(curl -sS -X POST "${ACCOUNTS_BASE}/oauth/v2/token" \
    --max-time 15 \
    -d "grant_type=refresh_token" \
    -d "client_id=${ZOHO_CLIENT_ID}" \
    -d "client_secret=${ZOHO_CLIENT_SECRET}" \
    -d "refresh_token=${ZOHO_REFRESH_TOKEN}" \
    | python3 -c "
import json, sys
try: d = json.load(sys.stdin)
except: sys.exit('failed to parse OAuth response')
if 'access_token' not in d:
    sys.exit(f'OAuth refresh failed: {d}')
print(d['access_token'])"); then
    return 1
  fi
  if [[ -z "${token}" ]]; then
    return 1
  fi
  # Store cache (mode 600) only on success
  printf '%s' "${token}" > "${CACHE_FILE}"
  chmod 600 "${CACHE_FILE}"
  printf '%s' "${token}"
}

do_call() {
  local token="$1"
  local body_file="$2"
  local headers_file="$3"
  curl -sS \
    -H "Authorization: Zoho-oauthtoken ${token}" \
    -H "Accept: application/json" \
    --max-time 30 \
    -o "${body_file}" \
    -D "${headers_file}" \
    -w "%{http_code}" \
    ${PASSTHRU[@]+"${PASSTHRU[@]}"} \
    "${MAIL_BASE}${API_PATH}"
}

ACCESS_TOKEN=$(get_access_token)
[[ -z "${ACCESS_TOKEN}" ]] && { echo "zoho-curl.sh: empty access_token" >&2; exit 1; }

BODY_FILE="$(mktemp -t zohocurl.XXXXXX)"
HEADERS_FILE="$(mktemp -t zohohdr.XXXXXX)"
trap 'rm -f "${BODY_FILE}" "${HEADERS_FILE}"' EXIT

HTTP_CODE=$(do_call "${ACCESS_TOKEN}" "${BODY_FILE}" "${HEADERS_FILE}")

# Retry once on 401 with a fresh token (handles edge cases of refresh-token rotation)
if [[ "${HTTP_CODE}" == "401" ]]; then
  ACCESS_TOKEN=$(get_access_token)
  HTTP_CODE=$(do_call "${ACCESS_TOKEN}" "${BODY_FILE}" "${HEADERS_FILE}")
fi

cat "${BODY_FILE}"
if [[ "${HTTP_CODE}" -ge 400 ]]; then
  echo "zoho-curl.sh: HTTP ${HTTP_CODE} on ${API_PATH}" >&2
  exit 1
fi
