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

ACTION="${1:-}"
MARKETPLACE_DIR="${2:-/tmp/graphit-plugin}"
VERSION=$(node -p "require('./cli/package.json').version")

sync_marketplace() {
  local target="$MARKETPLACE_DIR"

  mkdir -p "$target/skills/graphit"
  cp cli/skills/graphit/SKILL.md "$target/skills/graphit/SKILL.md"
  cp cli/skills/graphit/graphit.mdc "$target/skills/graphit/graphit.mdc"
  cp cli/skills/graphit/VERSION.json "$target/skills/graphit/VERSION.json"

  # Mirror generated directories so removed files cannot linger downstream.
  mkdir -p "$target/skills/graphit/references"
  rsync -a --delete cli/skills/graphit/references/ "$target/skills/graphit/references/"
  mkdir -p "$target/skills/graphit/cursor"
  rsync -a --delete cli/skills/graphit/cursor/ "$target/skills/graphit/cursor/"
  mkdir -p "$target/hooks"
  rsync -a --delete cli/hooks/ "$target/hooks/"

  mkdir -p "$target/scripts"
  cp cli/scripts/plugin-status.mjs "$target/scripts/"

  # Project #246: the public plugin ships wrappers that invoke the current CLI.
  mkdir -p "$target/bin"
  rsync -a --delete cli/bin/ "$target/bin/"
  chmod +x "$target/bin/graphit"

  # Feature #755: slash commands reach users through the git marketplace.
  mkdir -p "$target/commands"
  rsync -a --delete cli/commands/ "$target/commands/"

  mkdir -p "$target/.claude-plugin" "$target/.codex-plugin"
  cp cli/.claude-plugin/plugin.json "$target/.claude-plugin/plugin.json"
  cp cli/.codex-plugin/plugin.json "$target/.codex-plugin/plugin.json"
  cp cli/README.md "$target/README.md"

  python3 - "$target" "$VERSION" <<'PY'
import json
import sys
from pathlib import Path

marketplace_dir = Path(sys.argv[1])
version = sys.argv[2]
path = marketplace_dir / ".claude-plugin" / "marketplace.json"
with path.open(encoding="utf-8") as handle:
    marketplace = json.load(handle)
for plugin in marketplace.get("plugins", []):
    if plugin["name"] == "graphit":
        plugin["version"] = version
with path.open("w", encoding="utf-8") as handle:
    json.dump(marketplace, handle, indent=2)
    handle.write("\n")
PY

  echo "Synced plugin marketplace to $VERSION"
}

verify_marketplace() {
  local target="$MARKETPLACE_DIR"
  local fail=0

  for file in bin/graphit bin/graphit.cmd bin/graphit.ps1; do
    if [[ ! -f "$target/$file" ]]; then
      echo "::error::marketplace missing $file after sync"
      fail=1
    fi
  done

  if [[ -f "$target/bin/graphit" && ! -x "$target/bin/graphit" ]]; then
    echo "::error::marketplace bin/graphit lost its executable bit"
    fail=1
  fi

  if ! grep -Fq "FLOOR_VERSION=\"${VERSION}\"" "$target/bin/graphit" 2>/dev/null; then
    echo "::error::bin/graphit floor version != ${VERSION}"
    fail=1
  fi
  if ! grep -Fq "\$FloorVersion = \"${VERSION}\"" "$target/bin/graphit.ps1" 2>/dev/null; then
    echo "::error::bin/graphit.ps1 floor version != ${VERSION}"
    fail=1
  fi

  local marketplace_version claude_plugin_version codex_plugin_version skill_version
  local skill_frontmatter_version
  marketplace_version=$(node -p "require('$target/.claude-plugin/marketplace.json').plugins.find(p => p.name === 'graphit')?.version")
  claude_plugin_version=$(node -p "require('$target/.claude-plugin/plugin.json').version")
  codex_plugin_version=$(node -p "require('$target/.codex-plugin/plugin.json').version")
  skill_version=$(node -p "require('$target/skills/graphit/VERSION.json').version")
  skill_frontmatter_version=$(node -e "const fs=require('fs'); const m=fs.readFileSync('$target/skills/graphit/SKILL.md','utf8').match(/^skill_version:\\s*[\\\"']?([^\\\"'\\n]+)[\\\"']?\\s*$/m); console.log(m?.[1] ?? '')")

  if [[ "$marketplace_version" != "$VERSION" ]]; then
    echo "::error::marketplace.json graphit version ($marketplace_version) != package.json ($VERSION)"
    fail=1
  fi
  if [[ "$claude_plugin_version" != "$VERSION" ]]; then
    echo "::error::.claude-plugin/plugin.json version ($claude_plugin_version) != package.json ($VERSION)"
    fail=1
  fi
  if [[ "$codex_plugin_version" != "$VERSION" ]]; then
    echo "::error::.codex-plugin/plugin.json version ($codex_plugin_version) != package.json ($VERSION)"
    fail=1
  fi
  if [[ "$skill_version" != "$VERSION" ]]; then
    echo "::error::skills/graphit/VERSION.json version ($skill_version) != package.json ($VERSION)"
    fail=1
  fi
  if [[ "$skill_frontmatter_version" != "$VERSION" ]]; then
    echo "::error::skills/graphit/SKILL.md frontmatter version ($skill_frontmatter_version) != package.json ($VERSION)"
    fail=1
  fi

  if [[ "$fail" -ne 0 ]]; then
    echo "::error::post-sync integrity gate failed - refusing to push marketplace"
    exit 1
  fi
  echo "Integrity gate OK: bin/ present + executable, floor stamped ${VERSION}, all version surfaces match."
}

case "$ACTION" in
  sync)
    sync_marketplace
    ;;
  verify)
    verify_marketplace
    ;;
  *)
    echo "Usage: $0 {sync|verify} [marketplace-dir]" >&2
    exit 2
    ;;
esac
