#!/usr/bin/env bash
set -Eeuo pipefail

usage() {
  cat <<'EOF' >&2
usage: agentteam-staging-build-release.sh [--build-only] [artifact-dir]

Build a staging release bundle locally and, by default, activate it immediately.
This script always emits:
  - release-id
  - bundle path
  - checksums.txt path

If [artifact-dir] is omitted, artifacts are written to:
  .artifacts/staging/<release-id>

Environment overrides:
  AGENTTEAM_STAGING_RELEASE_ID            explicit release id (default: <timestamp>-<git short sha>)
  AGENTTEAM_STAGING_ARTIFACT_DIR          artifact directory when positional arg is omitted
  AGENTTEAM_STAGING_BUILD_ONLY            set to 1/true/yes to skip activation
  AGENTTEAM_STAGING_BUILD_RELEASE_SCRIPT  wrapper around scripts/release/build-release.sh
  AGENTTEAM_STAGING_ACTIVATE_RELEASE_SCRIPT  deploy helper (default: scripts/agentteam-staging-activate-release.sh)
  AGENTTEAM_STAGING_GOOS                  target OS for staging bundle (default: linux)
  AGENTTEAM_STAGING_GOARCH                target architecture for staging bundle (default: amd64)
  AGENTTEAM_DAEMON_MIN_VERSION            optional daemon hard gate persisted into the release metadata
EOF
}

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

on_error() {
  local exit_code="$?"
  local line="$1"
  local cmd="$2"
  fail "agentteam staging build release failed at line ${line}: ${cmd} (exit=${exit_code})"
}

trap 'on_error ${LINENO} "${BASH_COMMAND}"' ERR

require_command() {
  local cmd="$1"
  command -v "$cmd" >/dev/null 2>&1 || fail "missing required command: $cmd"
}

require_file() {
  local path="$1"
  [[ -f "$path" ]] || fail "required file not found: $path"
}

validate_release_env_value() {
  local key="$1"
  local value="$2"

  [[ "$value" != *$'\n'* ]] || fail "${key} must not contain newlines"
  [[ "$value" =~ ^[[:alnum:]/.+-]*$ ]] || fail "${key} must contain only semver-safe characters"
}

maybe_embed_release_env() {
  local bundle_path="$1"

  if [[ "${AGENTTEAM_DAEMON_MIN_VERSION+x}" != x ]]; then
    return 0
  fi

  local daemon_min_version="${AGENTTEAM_DAEMON_MIN_VERSION:-}"
  validate_release_env_value "AGENTTEAM_DAEMON_MIN_VERSION" "$daemon_min_version"

  local temp_dir
  temp_dir="$(mktemp -d "${TMPDIR:-/tmp}/agentteam-staging-release.XXXXXX")"
  tar -xzf "$bundle_path" -C "$temp_dir"
  printf 'AGENTTEAM_DAEMON_MIN_VERSION=%s\n' "$daemon_min_version" >"$temp_dir/release.env"
  tar -C "$temp_dir" -czf "$bundle_path" .
  rm -rf "$temp_dir"
}

readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
readonly REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
readonly DEFAULT_BUILD_SCRIPT="$REPO_ROOT/scripts/release/build-release.sh"
readonly DEFAULT_ACTIVATE_SCRIPT="$SCRIPT_DIR/agentteam-staging-activate-release.sh"

require_command bash
require_command date
require_command git
require_command mkdir
require_command mktemp
require_command sha256sum
require_command tar

build_only="${AGENTTEAM_STAGING_BUILD_ONLY:-}"
if [[ "$build_only" == "1" || "$build_only" == "true" || "$build_only" == "yes" ]]; then
  build_only=1
else
  build_only=0
fi

artifact_dir_arg=''
while [[ $# -gt 0 ]]; do
  case "$1" in
    --build-only)
      build_only=1
      shift
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    --*)
      usage
      exit 1
      ;;
    *)
      if [[ -n "$artifact_dir_arg" ]]; then
        usage
        exit 1
      fi
      artifact_dir_arg="$1"
      shift
      ;;
  esac
done

build_release_script="${AGENTTEAM_STAGING_BUILD_RELEASE_SCRIPT:-$DEFAULT_BUILD_SCRIPT}"
require_file "$build_release_script"
activate_release_script="${AGENTTEAM_STAGING_ACTIVATE_RELEASE_SCRIPT:-$DEFAULT_ACTIVATE_SCRIPT}"
if [[ "$build_only" != "1" ]]; then
  require_file "$activate_release_script"
fi

if [[ -n "${AGENTTEAM_STAGING_RELEASE_ID:-}" ]]; then
  release_id="$AGENTTEAM_STAGING_RELEASE_ID"
else
  release_id="$(date +%Y%m%d%H%M%S)-$(git -C "$REPO_ROOT" rev-parse --short HEAD)"
fi
[[ -n "$release_id" ]] || fail "release id must not be empty"

if [[ -n "$artifact_dir_arg" ]]; then
  artifact_dir="$artifact_dir_arg"
elif [[ -n "${AGENTTEAM_STAGING_ARTIFACT_DIR:-}" ]]; then
  artifact_dir="$AGENTTEAM_STAGING_ARTIFACT_DIR"
else
  artifact_dir="$REPO_ROOT/.artifacts/staging/$release_id"
fi

target_goos="${AGENTTEAM_STAGING_GOOS:-linux}"
target_goarch="${AGENTTEAM_STAGING_GOARCH:-amd64}"

bundle_path="$artifact_dir/agentteam-release-$release_id.tar.gz"
checksum_path="$artifact_dir/checksums.txt"
release_id_path="$artifact_dir/release-id.txt"

mkdir -p "$artifact_dir"

AGENTTEAM_RELEASE_GOOS="$target_goos" \
AGENTTEAM_RELEASE_GOARCH="$target_goarch" \
AGENTTEAM_RELEASE_ARCHIVE_PATH="$bundle_path" \
  bash "$build_release_script"
[[ -f "$bundle_path" ]] || fail "release bundle was not created: $bundle_path"
maybe_embed_release_env "$bundle_path"

sha256sum "$bundle_path" >"$checksum_path"
printf '%s\n' "$release_id" >"$release_id_path"

cat <<EOF
release_id=$release_id
artifact_dir=$artifact_dir
release_id_path=$release_id_path
bundle_path=$bundle_path
checksum_path=$checksum_path
EOF

if [[ "$build_only" == "1" ]]; then
  exit 0
fi

bash "$activate_release_script" "$bundle_path" "$checksum_path" "$release_id"
