"""Bash script templates and attestation examples for hooks."""


def example_attestation() -> str:
    """Return the example attestation file content.

    This is saved to .gjalla/example-attestation.yaml so agents have
    a concrete reference for the required format.
    """
    return '''---
# Gjalla Commit Attestation — write this as .gjalla/.commit-attestation.yaml
#
# The pre-commit hook validates this file before allowing a commit.
# The post-commit hook saves it to .gjalla/attestations/<hash>.yaml.
#
# How to fill this out:
#   1. Stage your changes (git add ...)
#   2. Compute the diff hash:  git diff --staged | shasum -a 256
#   3. Fetch project rules, current state (architecture, etc.)
#      via the gjalla MCP server (get_project_rules,
#      get_architecture_spec, get_current_state, etc.)
#   4. Fill in ALL fields below and save as .gjalla/.commit-attestation.yaml
#   5. Run git commit — the hook will verify the hash matches.
#
# IMPORTANT: Do NOT stage or commit this file. It is consumed by the
# post-commit hook and cleaned up automatically.

# REQUIRED — must match `git diff --staged | shasum -a 256` at commit time.
staged_diff_hash: "abc123..."

# REQUIRED — ISO 8601 timestamp of when this attestation was created.
timestamp: "2026-02-11T12:00:00Z"

# REQUIRED — the name of the coding agent (e.g. "claude-code", "cursor", "aider").
agent: "claude-code"

# REQUIRED — who provides the model (e.g. "anthropic", "openai", "google").
agent_provider: "anthropic"

# REQUIRED — the specific model used (e.g. "claude-opus-4-6", "gpt-4o").
agent_model: "claude-opus-4-6"

# RECOMMENDED — if you have an identifier that isn't captured in the fields above, include it here.
agent_id: "cc_1234567890"

# REQUIRED — did you check the project rules before committing?
#
# Status values:
#   "compliant"      — code follows the rule, no action needed.
#   "not-applicable" — rule doesn't apply to this change.
#   "remediated"     — was non-compliant; agent fixed it. Human should spot-check.
#   "needs-review"   — agent couldn't fix or can't determine compliance. Human must review.
#
# If you find non-compliance, fix it if you can and report "remediated".
# If you can't fix it or aren't sure, report "needs-review" with an explanation.
# Do not commit with known, un-addressed non-compliance without at minimum
# flagging it as "needs-review".
rules:
  checked: true
  # List each rule you reviewed. Use the rule names from get_project_rules.
  applicable:
    - id: "separation-of-concerns"
      status: "compliant"
    - id: "no-source-code-in-db"
      status: "not-applicable"
    - id: "example-remediated-rule"
      status: "remediated"
      note: "Inlined a DB query that belonged in the repository layer; moved it."
    - id: "example-needs-review-rule"
      status: "needs-review"
      note: "Unclear whether new caching layer violates this rule; needs human judgment."

# REQUIRED — self-report changes to architecture primitives.
# All 8 canonical primitives go under the `changes` key.
# Set changed: true/false for each. If true, include a details list.
# Use names from the project architecture (get_architecture_spec).
changes:
  # Architecture — elements, connections, and decisions
  architecture:
    elements:
      - modified: "web-api — added rate limiting middleware layer"
    connections:
      - added: "web-api → redis — rate limit counters"
    decisions:
      - "Use token-bucket rate limiting at the gateway, not per-service"

  # Data model — entity/schema changes
  data_model:
    changed: false

  # Data flows
  data_flows:
    changed: false

  # Rules — ADRs, principles, invariants
  rules:
    changed: false

  # Capabilities
  capabilities:
    changed: false

  # API surface — endpoint additions/modifications/removals
  api_surface:
    changed: false

  # External dependencies & services
  external_dependencies:
    changed: true
    details:
      - added: "rate-limiter-flexible@^5.0.0"
      - updated: "express@4.18 → 4.19"
      - added: "Redis (Upstash) — rate limit counter store"

  # Tech stack
  tech_stack:
    changed: false

# REQUIRED — one-line impact summary (not a commit message).
# Focus on the SO WHAT of the changes in this commit. This should be
# more about the purpose than a commit message would be.
#   Good: "New rate limiting additions help protect the API from abuse"
#   Bad:  "Added rate limiting middleware to auth endpoints"
summary: "Auth endpoints now enforce token-bucket rate limiting"
---
'''


def attestation_pre_commit_script() -> str:
    """Return the attestation pre-commit check script."""
    return r'''#!/usr/bin/env bash
set -euo pipefail
# Gjalla Attestation Gate — agent-agnostic, no Python required

GJALLA_CONFIG=".gjalla/config.yaml"
# Support config.yaml, legacy config.json, and old (.gjalla file) formats
[ ! -f "$GJALLA_CONFIG" ] && GJALLA_CONFIG=".gjalla/config.json"
[ ! -f "$GJALLA_CONFIG" ] && GJALLA_CONFIG=".gjalla"
[ ! -f "$GJALLA_CONFIG" ] && exit 0
if [ "${SKIP_ATTESTATION:-0}" = "1" ]; then
  echo "[gjalla] Attestation skipped (SKIP_ATTESTATION=1)" >&2
  if command -v git &>/dev/null; then
    SKIP_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
    mkdir -p .gjalla/attestations
    echo "{\"event\":\"attestation_skipped\",\"branch\":\"${SKIP_BRANCH}\",\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"synced\":false}" >> .gjalla/log.jsonl
  fi
  exit 0
fi

# Soft check — inform if gjalla CLI is not installed (not blocking)
if ! command -v gjalla &>/dev/null; then
  echo "[gjalla] CLI not installed. Attestation uploads require it."
  echo "[gjalla] Install: pip install gjalla  (or: pipx install gjalla)"
fi

ATTESTATION=".gjalla/.commit-attestation.yaml"
if [ ! -f "$ATTESTATION" ]; then
  DIFF_HASH=$(git diff --staged | { shasum -a 256 2>/dev/null || sha256sum 2>/dev/null; } | cut -d' ' -f1)
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo "  gjalla: Attestation Required"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo ""
  echo "  staged_diff_hash: $DIFF_HASH"
  echo ""
  echo "  [Human] Run the interactive attestation command:"
  echo ""
  echo "    gjalla attest"
  echo ""
  echo "  To skip attestation: SKIP_ATTESTATION=1 git commit ..."
  echo ""
  echo "  [AI Agent] Create .gjalla/.commit-attestation.yaml before committing:"
  echo ""
  echo "    1. Use the example at .gjalla/example-attestation.yaml for the format"
  echo "    2. Set staged_diff_hash to: $DIFF_HASH"
  echo "    3. Fetch rules (get_project_rules) and architecture (get_architecture_spec)"
  echo "    4. Check that your changes comply with all applicable rules BEFORE attesting"
  echo "    5. Fill in ALL primitives under the changes: key: architecture (elements,"
  echo "       connections, decisions), data_model, data_flows, rules, capabilities,"
  echo "       api_surface, external_dependencies, tech_stack"
  echo "    6. Write the file, then retry git commit"
  echo ""
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  exit 1
fi

# Validate diff hash
CURRENT=$(git diff --staged | { shasum -a 256 2>/dev/null || sha256sum 2>/dev/null; } | cut -d' ' -f1)
ATTESTED=$(grep -m1 'staged_diff_hash:' "$ATTESTATION" | sed 's/.*staged_diff_hash: *//' | tr -d "\"'")
if [ "$CURRENT" != "$ATTESTED" ]; then
  echo "[gjalla] Attestation stale — staged changes differ from attested hash"
  echo "  Expected: ${ATTESTED:0:16}..."
  echo "  Current:  ${CURRENT:0:16}..."
  exit 1
fi
echo "[gjalla] Attestation verified"

# Check cache freshness (non-blocking warning)
if [ -f ".gjalla/config.json" ]; then
  LAST_SYNCED=$(python3 -c "import json,sys;c=json.load(open('.gjalla/config.json'));print(c.get('cache',{}).get('last_synced',''))" 2>/dev/null || true)
  if [ -n "$LAST_SYNCED" ]; then
    STALE=$(python3 -c "
from datetime import datetime,timezone
import json,sys
c=json.load(open('.gjalla/config.json'))
ls=c.get('cache',{}).get('last_synced','')
hrs=c.get('cache',{}).get('stale_after_hours',24)
t=datetime.fromisoformat(ls.replace('Z','+00:00'))
age=(datetime.now(timezone.utc)-t).total_seconds()/3600
if age>hrs:
    d=int(age//24) or 1
    print(f'{d}')
" 2>/dev/null || true)
    if [ -n "$STALE" ]; then
      echo "[gjalla] Warning: Project context cache is ${STALE} day(s) old. Run 'gjalla sync' to refresh." >&2
    fi
  fi
fi
'''


def post_commit_upload_script() -> str:
    """Return the post-commit upload script."""
    return r'''#!/usr/bin/env bash
# Gjalla Post-Commit — always save attestation locally, then attempt upload.
ATTESTATION=".gjalla/.commit-attestation.yaml"
[ ! -f "$ATTESTATION" ] && exit 0

COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
TIMESTAMP=$(grep -m1 'timestamp:' "$ATTESTATION" | sed 's/.*timestamp: *//' | tr -d "\"'" 2>/dev/null || echo "")
AGENT=$(grep -m1 'agent:' "$ATTESTATION" | grep -v 'agent_' | sed 's/.*agent: *//' | tr -d "\"'" 2>/dev/null || echo "")
AGENT_ID=$(grep -m1 'agent_id:' "$ATTESTATION" | sed 's/.*agent_id: *//' | tr -d "\"'" 2>/dev/null || echo "")
SUMMARY=$(grep -m1 'summary:' "$ATTESTATION" | sed 's/.*summary: *//' | tr -d "\"'" 2>/dev/null || echo "")

# Always save full attestation locally
mkdir -p .gjalla/attestations
cp "$ATTESTATION" ".gjalla/attestations/${COMMIT}.yaml"

# Migrate legacy .gjallalog if present
[ -f .gjallalog ] && cat .gjallalog >> .gjalla/log.jsonl && rm -f .gjallalog

# Clean up attestation file BEFORE calling sync, so sync's
# _process_pending_attestation sees no file and doesn't double-process.
rm -f "$ATTESTATION"

# Attempt upload if CLI is available
SYNCED=false
if command -v gjalla &>/dev/null; then
  if gjalla sync 2>/dev/null; then
    SYNCED=true
    echo "[gjalla] Attestation saved and uploaded."
  else
    echo "[gjalla] Attestation saved locally. Upload failed — run 'gjalla sync' later."
  fi
else
  echo "[gjalla] Attestation saved locally. Install CLI for auto-upload: pipx install gjalla"
fi

# Always log to .gjalla/log.jsonl (after sync so SYNCED reflects actual result)
json_escape() { python3 -c "import sys,json; print(json.dumps(sys.argv[1]))" "$1" 2>/dev/null || printf '"%s"' "$(printf '%s' "$1" | sed 's/\\/\\\\/g;s/"/\\"/g')"; }
AGENT_ID_FIELD=""
[ -n "$AGENT_ID" ] && AGENT_ID_FIELD=",\"agent_id\":$(json_escape "$AGENT_ID")"
echo "{\"commit\":$(json_escape "$COMMIT"),\"branch\":$(json_escape "$BRANCH"),\"timestamp\":$(json_escape "$TIMESTAMP"),\"agent\":$(json_escape "$AGENT")${AGENT_ID_FIELD},\"summary\":$(json_escape "$SUMMARY"),\"synced\":${SYNCED}}" >> .gjalla/log.jsonl
exit 0
'''
