#!/usr/bin/env bats

# Tests for scripts/check-no-upstream-edits.sh

setup() {
  REPO_ROOT="$(git rev-parse --show-toplevel)"
  SCRIPT="$REPO_ROOT/scripts/check-no-upstream-edits.sh"
  TMP_REPO=""
}

teardown() {
  if [ -n "$TMP_REPO" ] && [ -d "$TMP_REPO" ]; then
    rm -rf "$TMP_REPO"
  fi
}

# --- Helpers ---

# Build a minimal disposable repo that mimics the sethLabels structure with a
# local "upstream/master" ref. Returns its path via stdout.
make_test_repo() {
  local tmp=$(mktemp -d)
  cd "$tmp"
  git init -q -b master
  git config user.email "test@test"
  git config user.name "test"
  # Pretend-upstream files
  echo "upstream content" > UPSTREAM_FILE.md
  echo "real source" > glabels-source.cpp
  git add UPSTREAM_FILE.md glabels-source.cpp
  git commit -m "upstream base" -q
  # Create a local "upstream/master" ref pointing here
  git update-ref refs/remotes/upstream/master HEAD
  # Create a feature branch for sethLabels content
  git checkout -q -b main
  echo "$tmp"
}

# --- Tests ---

@test "script exists and is executable" {
  [ -x "$SCRIPT" ]
}

@test "exits 0 on clean state with only allowlisted committed changes" {
  TMP_REPO=$(make_test_repo)
  cd "$TMP_REPO"
  mkdir -p scripts packaging sethlabels-docs .claude/handoffs
  echo "test" > CLAUDE.md
  echo "test" > scripts/something.sh
  echo "test" > packaging/x.env
  echo "test" > sethlabels-docs/spec.md
  echo "" >> .gitignore
  git add -A
  git commit -m "sethLabels additions" -q

  run "$SCRIPT"
  [ "$status" -eq 0 ]
  [ -z "$output" ]
}

@test "exits 1 when an upstream file is committed-modified" {
  TMP_REPO=$(make_test_repo)
  cd "$TMP_REPO"
  echo "evil edit" >> glabels-source.cpp
  git add glabels-source.cpp
  git commit -m "BAD: edit upstream file" -q

  run "$SCRIPT"
  [ "$status" -eq 1 ]
  [[ "$output" == *"glabels-source.cpp"* ]]
  [[ "$output" == *"strict-zero"* ]]
}

@test "exits 1 when an upstream file has uncommitted working-tree edits" {
  TMP_REPO=$(make_test_repo)
  cd "$TMP_REPO"
  echo "uncommitted evil edit" >> glabels-source.cpp

  run "$SCRIPT"
  [ "$status" -eq 1 ]
  [[ "$output" == *"glabels-source.cpp"* ]]
}

@test "exits 0 when only .gitignore is modified (allowlisted)" {
  TMP_REPO=$(make_test_repo)
  cd "$TMP_REPO"
  echo "*.tmp" >> .gitignore
  git add .gitignore
  git commit -m "extend gitignore" -q

  run "$SCRIPT"
  [ "$status" -eq 0 ]
}

@test "exits 0 when only CLAUDE.md / IDEA.md / DECISIONS.md / README.sethlabels.md are added" {
  TMP_REPO=$(make_test_repo)
  cd "$TMP_REPO"
  echo "x" > CLAUDE.md
  echo "x" > IDEA.md
  echo "x" > DECISIONS.md
  echo "x" > README.sethlabels.md
  git add -A
  git commit -m "add sethLabels root docs" -q

  run "$SCRIPT"
  [ "$status" -eq 0 ]
}

@test "exits 1 when upstream/master ref is missing" {
  TMP_REPO=$(make_test_repo)
  cd "$TMP_REPO"
  # Delete the upstream/master ref we set in make_test_repo.
  git update-ref -d refs/remotes/upstream/master
  # Modify an upstream file in working tree — would normally trigger violation.
  echo "edit" >> glabels-source.cpp

  run "$SCRIPT"
  [ "$status" -eq 1 ]
  [[ "$output" == *"upstream/master ref not found"* || "$stderr" == *"upstream/master ref not found"* ]]
}
