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

if (($# != 1)); then
  echo "usage: $0 <github-user-module-download.sh>" >&2
  exit 64
fi

downloader=$1
[[ -x "$downloader" ]] || {
  echo "GitHub module downloader is not executable: $downloader" >&2
  exit 65
}

root=$(mktemp -d /tmp/cp9-github-security.XXXXXX)
case "$root" in
  /tmp/cp9-github-security.*) ;;
  *) echo "unexpected security workspace: $root" >&2; exit 65 ;;
esac
cleanup() {
  rm -rf -- "$root"
}
trap cleanup EXIT HUP INT TERM

confirmed_fail() {
  printf '{"status":"fail","reason":"%s"}\n' "$1"
  exit 10
}

for command in bash grep sha256sum; do
  command -v "$command" >/dev/null 2>&1 || {
    echo "required remote command is missing: $command" >&2
    exit 20
  }
done

mkdir -p "$root/bin" "$root/tmp" "$root/module"
printf 'module cp9.security/residue\n' >"$root/module/go.mod"
token="ghu_fixture_${RANDOM}_$$"
pattern_file="$root/token-pattern"
printf '%s' "$token" >"$pattern_file"
chmod 600 "$pattern_file"
token_sha256=$(printf '%s' "$token" | sha256sum | cut -d' ' -f1)

cat >"$root/bin/go" <<'FAKEGO'
#!/usr/bin/env bash
set -Eeuo pipefail
password=$("$GIT_ASKPASS" "Password for 'https://x-access-token@github.com':")
actual_sha256=$(printf '%s' "$password" | sha256sum | cut -d' ' -f1)
unset password
[[ "$actual_sha256" == "$FAKE_TOKEN_SHA256" ]]
count=0
[[ ! -f "$FAKE_GO_ROOT/count" ]] || count=$(<"$FAKE_GO_ROOT/count")
count=$((count + 1))
printf '%s' "$count" >"$FAKE_GO_ROOT/count"
if ((count == 1)); then
  : >"$FAKE_GO_ROOT/ready"
  deadline=$((SECONDS + 30))
  while [[ ! -f "$FAKE_GO_ROOT/continue" && $SECONDS -lt $deadline ]]; do
    sleep 0.1
  done
  [[ -f "$FAKE_GO_ROOT/continue" ]]
fi
[[ "$FAKE_GO_MODE" == success ]]
FAKEGO
chmod 700 "$root/bin/go"

argv_token_matches=0
log_token_matches=0
run_helper() {
  local mode=$1 expected_rc=$2 case_root="$root/$1" helper_pid rc=0 deadline
  mkdir -p "$case_root"
  rm -f "$case_root/ready" "$case_root/continue" "$case_root/count"
  printf '%s' "$token" |
    env PATH="$root/bin:$PATH" TMPDIR="$root/tmp" \
      FAKE_GO_ROOT="$case_root" FAKE_GO_MODE="$mode" \
      FAKE_TOKEN_SHA256="$token_sha256" \
      "$downloader" "$root/module" \
      >"$case_root/stdout.log" 2>"$case_root/stderr.log" &
  helper_pid=$!

  deadline=$((SECONDS + 30))
  while [[ ! -f "$case_root/ready" && $SECONDS -lt $deadline ]]; do
    kill -0 "$helper_pid" 2>/dev/null || break
    sleep 0.1
  done
  [[ -f "$case_root/ready" ]] || {
    kill "$helper_pid" 2>/dev/null || true
    wait "$helper_pid" 2>/dev/null || true
    echo "$mode helper did not reach the credential-use checkpoint" >&2
    exit 20
  }

  for cmdline in /proc/[0-9]*/cmdline; do
    [[ -r "$cmdline" ]] || continue
    if grep -Fq -f "$pattern_file" "$cmdline" 2>/dev/null; then
      argv_token_matches=$((argv_token_matches + 1))
    fi
  done
  : >"$case_root/continue"
  set +e
  wait "$helper_pid"
  rc=$?
  set -e
  if [[ "$expected_rc" == zero && $rc -ne 0 ]] ||
    [[ "$expected_rc" == nonzero && $rc -eq 0 ]]; then
    echo "$mode helper rc=$rc did not match expected $expected_rc" >&2
    exit 20
  fi
  if grep -Fq -f "$pattern_file" "$case_root/stdout.log" "$case_root/stderr.log"; then
    log_token_matches=$((log_token_matches + 1))
  fi
  if find "$root/tmp" -mindepth 1 -name 'cp9-github-user.*' -print -quit | grep -q .; then
    confirmed_fail "$mode left a cp9-github-user temporary path"
  fi
}

run_helper success zero
run_helper failure nonzero

credential_env_names=0
for environ in /proc/[0-9]*/environ; do
  [[ -r "$environ" ]] || continue
  if tr '\0' '\n' <"$environ" 2>/dev/null |
    cut -d= -f1 | grep -Eq '^(CP9_GITHUB_USER_TOKEN_FILE|GIT_ASKPASS)$'; then
    credential_env_names=$((credential_env_names + 1))
  fi
done

scan_roots=("$root")
[[ ! -d "${HOME}/.cp9" ]] || scan_roots+=("${HOME}/.cp9")
token_cache_files=$(find "${scan_roots[@]}" -type f \
  -name 'github-app-user-token.json' -print 2>/dev/null | wc -l | tr -d ' ')
askpass_files=$(find "${scan_roots[@]}" -type f \
  -name 'askpass.sh' -print 2>/dev/null | wc -l | tr -d ' ')
temporary_paths=$(find "$root/tmp" -mindepth 1 -name 'cp9-github-user.*' \
  -print 2>/dev/null | wc -l | tr -d ' ')

((argv_token_matches == 0)) || confirmed_fail "credential appeared in process argv"
((log_token_matches == 0)) || confirmed_fail "credential appeared in helper logs"
((credential_env_names == 0)) || confirmed_fail "credential environment remained after helper exit"
((token_cache_files == 0)) || confirmed_fail "token cache remained on EC2"
((askpass_files == 0)) || confirmed_fail "AskPass file remained on EC2"
((temporary_paths == 0)) || confirmed_fail "temporary credential path remained on EC2"

rm -f -- "$pattern_file"
unset token
printf '%s\n' '{"status":"pass","success_helper_rc":0,"failure_helper_rc":"nonzero","temporary_paths":0,"token_cache_files":0,"askpass_files":0,"credential_env_names":0,"argv_token_matches":0,"log_token_matches":0}'
