#!/bin/bash
set -euo pipefail

# Build autowonder-daemon binaries and publish npm package.
# Run from the autowonder-npm directory.
#
# Prerequisites:
#   - Go 1.22+
#   - Access to gitlab.alibaba-inc.com
#   - NPM_TOKEN env var set
#
# Usage:
#   ./scripts/build-and-publish.sh           # build + publish
#   ./scripts/build-and-publish.sh --build   # build only (no publish)

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PKG_DIR="$(dirname "$SCRIPT_DIR")"
VENDOR_DIR="$PKG_DIR/vendor"
SOURCE_DIR="${AUTOWONDER_SOURCE_DIR:-}"
SOURCE_REPO="${AUTOWONDER_SOURCE_REPO:-}"
TEMP_SELECTED_SOURCE_DIR=""
TEMP_BUILD_PARENT=""
STAGING_VENDOR_DIR=""
NPM_CONFIG_FILE=""

source "$SCRIPT_DIR/release-build-lib.sh"

cleanup() {
  if [[ -n "$TEMP_SELECTED_SOURCE_DIR" ]]; then
    rm -rf "$TEMP_SELECTED_SOURCE_DIR"
  fi
  if [[ -n "$TEMP_BUILD_PARENT" ]]; then
    rm -rf "$TEMP_BUILD_PARENT"
  fi
  if [[ -n "$STAGING_VENDOR_DIR" ]]; then
    rm -rf "$STAGING_VENDOR_DIR"
  fi
  if [[ -n "$NPM_CONFIG_FILE" ]]; then
    rm -f "$NPM_CONFIG_FILE"
  fi
}
trap cleanup EXIT

BUILD_ONLY=false
if [[ "${1:-}" == "--build" ]]; then
  BUILD_ONLY=true
fi

echo "━━━ autowonder npm build ━━━"

# Get source code
if [[ -z "$SOURCE_DIR" && -f "$PKG_DIR/../go.mod" ]]; then
  SOURCE_DIR="$(cd "$PKG_DIR/.." && pwd)"
fi

if [[ -n "$SOURCE_DIR" && -d "$SOURCE_DIR" ]]; then
  echo "Using local source: $SOURCE_DIR"
else
  if [[ -z "$SOURCE_REPO" ]]; then
    echo "Error: set AUTOWONDER_SOURCE_DIR or AUTOWONDER_SOURCE_REPO"
    exit 1
  fi
  TEMP_SELECTED_SOURCE_DIR="$(mktemp -d)"
  SOURCE_DIR="$TEMP_SELECTED_SOURCE_DIR"
  echo "Cloning from $SOURCE_REPO..."
  git clone --depth 1 "$SOURCE_REPO" "$SOURCE_DIR"
fi

version="$(node -p "require('$PKG_DIR/package.json').version")"
require_clean_release_source "$SOURCE_DIR"
release_commit="$(git -C "$SOURCE_DIR" rev-parse HEAD)"
commit="${release_commit:0:12}"

TEMP_BUILD_PARENT="$(mktemp -d)"
BUILD_SOURCE_DIR="$TEMP_BUILD_PARENT/source"
prepare_clean_release_checkout "$SOURCE_DIR" "$release_commit" "$BUILD_SOURCE_DIR"

source_version="$(node -p "require('$BUILD_SOURCE_DIR/npm/package.json').version")"
if [[ "$source_version" != "$version" ]]; then
  release_error "package version mismatch: source=$source_version package=$version"
  exit 1
fi

ldflags="-s -w -X main.buildPackageName=autowonder -X main.buildVersion=$version -X main.buildCommit=$commit"
echo "Release commit: $release_commit"
echo "Go toolchain: $(go env GOVERSION)"

# Build for all platforms
STAGING_VENDOR_DIR="$(mktemp -d "$PKG_DIR/.vendor-staging.XXXXXX")"

platforms=("darwin-arm64" "darwin-amd64" "linux-amd64" "linux-arm64" "windows-amd64" "windows-arm64")
goarch_map=("arm64" "amd64" "amd64" "arm64" "amd64" "arm64")
goos_map=("darwin" "darwin" "linux" "linux" "windows" "windows")
filename_map=("autowonder-daemon-darwin-arm64" "autowonder-daemon-darwin-amd64" "autowonder-daemon-linux-amd64" "autowonder-daemon-linux-arm64" "autowonder-daemon-win32-amd64.exe" "autowonder-daemon-win32-arm64.exe")

for i in "${!platforms[@]}"; do
  platform="${platforms[$i]}"
  goos="${goos_map[$i]}"
  goarch="${goarch_map[$i]}"
  filename="${filename_map[$i]}"
  output="$STAGING_VENDOR_DIR/$filename"

  echo "Building $platform..."
  (cd "$BUILD_SOURCE_DIR" && CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" go build -trimpath -buildvcs=true -o "$output" -ldflags="$ldflags" ./cmd/autowonder-daemon)
  if [[ "$goos" != "windows" ]]; then
    chmod +x "$output"
  fi
  verify_go_binary_provenance "$output" "$release_commit" "$goos" "$goarch"
  echo "  -> $output ($(du -h "$output" | cut -f1))"
done

native_goos="$(go env GOOS)"
native_goarch="$(go env GOARCH)"
native_binary="$STAGING_VENDOR_DIR/autowonder-daemon-${native_goos}-${native_goarch}"
if [[ ! -x "$native_binary" ]]; then
  release_error "native platform is not included in release targets: ${native_goos}-${native_goarch}"
  exit 1
fi
verify_daemon_self_check "$native_binary" "$version" "$commit" "$native_goos" "$native_goarch"

rm -rf "$VENDOR_DIR"
mv "$STAGING_VENDOR_DIR" "$VENDOR_DIR"
STAGING_VENDOR_DIR=""

echo ""
echo "Binaries ready in $VENDOR_DIR:"
ls -lh "$VENDOR_DIR/"

if [[ "$BUILD_ONLY" == "true" ]]; then
  echo ""
  echo "Build complete. Skipping publish (--build flag)."
  exit 0
fi

# Publish
echo ""
echo "━━━ Publishing to npm ━━━"
cd "$PKG_DIR"

if [[ -z "${NPM_TOKEN:-}" ]]; then
  echo "Error: NPM_TOKEN is not set"
  exit 1
fi

umask 077
NPM_CONFIG_FILE="$(mktemp)"
printf '//registry.npmjs.org/:_authToken=%s\n' "$NPM_TOKEN" > "$NPM_CONFIG_FILE"
npm publish --access public --userconfig "$NPM_CONFIG_FILE"

echo ""
echo "Published $(node -p "require('./package.json').name + '@' + require('./package.json').version")"
