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

ACTION="${1:-setup}"
ROOT="${2:-/tmp/soria-bts-data-identity-${USER:-student}}"
MARKER=".soria-bts-data-identity-evidence"

fail(){ printf 'ERROR: %s\n' "$*" >&2; exit 1; }

safe_root(){
  case "$ROOT" in
    /tmp/soria-bts-*|"$HOME"/soria-bts-*) ;;
    *) fail "refused lab root: $ROOT" ;;
  esac
  [[ "$ROOT" != "/tmp" && "$ROOT" != "$HOME" ]] || fail "unsafe lab root"
}

require_marker(){ [[ -f "$ROOT/$MARKER" ]] || fail "missing marker: $ROOT/$MARKER"; }
rows(){ awk 'END { print (NR > 0 ? NR - 1 : 0) }' "$1"; }

setup_lab(){
  safe_root
  if [[ -e "$ROOT" ]]; then
    require_marker
    rm -rf "$ROOT/input" "$ROOT/output" "$ROOT/evidence"
  else
    mkdir -p "$ROOT"
    : > "$ROOT/$MARKER"
  fi
  mkdir -p "$ROOT/input" "$ROOT/output" "$ROOT/evidence"

  cat > "$ROOT/input/treatments.csv" <<'CSV'
treatment_id,purpose,people,data_categories,legal_basis,recipients,retention,processor,security_owner
TRT-001,Manage training registrations,learners,identity|contact|registration,contract,training_team,3y,training_saas,security_owner
TRT-002,Send optional newsletter,prospects,email|preferences,,marketing,until_unsubscribe,email_provider,marketing_owner
TRT-003,Manage support tickets,users,identity|contact|technical_logs,legitimate_interest,support_team|it,2y,service_desk,it_owner
TRT-004,Old shared spreadsheet,employees,identity|bank_details,unknown,all_staff,unlimited,none,unknown
CSV

  cat > "$ROOT/input/lifecycle.csv" <<'CSV'
case_id,purpose_defined,minimized,information_ready,rights_process,retention_defined,security_controls,decision
LIFE-001,yes,yes,yes,yes,yes,yes,READY
LIFE-002,yes,no,yes,yes,yes,yes,ACTION_REQUIRED
LIFE-003,yes,yes,no,yes,yes,yes,ACTION_REQUIRED
LIFE-004,yes,yes,yes,yes,no,yes,ACTION_REQUIRED
LIFE-005,no,no,no,no,no,no,BLOCK_DESIGN
CSV

  cat > "$ROOT/input/awareness.csv" <<'CSV'
audience,risk,rule,exercise,evidence
support,identity-verification,verify-before-disclosure,synthetic-rights-request,exercise_record
administrators,bulk-export,approved-export-and-logging,export-review,review_record
hr,sensitive-data-sharing,approved-recipient-only,recipient-classification,scenario_result
direction,supplier-change,privacy-review-before-change,tabletop-change-review,decision_record
CSV

  cat > "$ROOT/input/identity-assets.csv" <<'CSV'
asset_id,asset_type,owner,mfa,recovery,dependency,review_status
ID-001,domain,infra_owner,yes,role_mailbox,public_web|mail,READY
ID-002,dns_zone,infra_owner,yes,role_mailbox,domain|certificates,READY
ID-003,certificate_inventory,infra_owner,yes,role_mailbox,public_web,ACTION_REQUIRED
ID-004,institutional_social_account,communications,no,personal_mailbox,public_identity,ACTION_REQUIRED
ID-005,source_code_org,engineering_owner,yes,role_mailbox,software_delivery,READY
ID-006,legacy_cloud_tenant,unknown,no,former_employee_mailbox,service_recovery,BLOCK_RECOVERY
CSV

  cat > "$ROOT/input/evidence-needs.csv" <<'CSV'
evidence_id,need,mechanism,identity_bound,time_bound,preservation,expected
EV-001,detect-content-change,hash,no,no,original_and_hash,INTEGRITY_ONLY
EV-002,person-approval,signature,yes,no,signed_original_and_validation,IDENTITY_AND_INTEGRITY
EV-003,organisation-origin,electronic_seal,yes,no,sealed_original_and_validation,ORGANISATION_ORIGIN
EV-004,prove-time-binding,qualified_timestamp,no,yes,original_timestamp_validation,TIME_AND_INTEGRITY_PRESUMPTION
EV-005,legal-case-complete,hash,no,no,screenshot_only,INSUFFICIENT_CONTEXT
CSV

  cat > "$ROOT/input/proof-boundary.md" <<'MD'
# Frontière de preuve

SYNTHETIC — TRAINING ONLY.

Le laboratoire n'utilise aucune donnée personnelle réelle, aucun compte, domaine, certificat ou prestataire réel. Il n'effectue aucune requête réseau, ne crée aucune signature réelle, ne contacte aucun service de confiance et ne produit aucune conclusion juridique. Les décisions générées servent uniquement à l'entraînement BTS.
MD

  (cd "$ROOT" && sha256sum input/* > evidence/sources-before.sha256)
  printf 'BTS data/identity/evidence lab ready: %s\n' "$ROOT"
}

status_lab(){
  require_marker
  printf 'Treatments: %s\n' "$(rows "$ROOT/input/treatments.csv")"
  printf 'Lifecycle cases: %s\n' "$(rows "$ROOT/input/lifecycle.csv")"
  printf 'Awareness audiences: %s\n' "$(rows "$ROOT/input/awareness.csv")"
  printf 'Identity assets: %s\n' "$(rows "$ROOT/input/identity-assets.csv")"
  printf 'Evidence needs: %s\n' "$(rows "$ROOT/input/evidence-needs.csv")"
  [[ -f "$ROOT/output/summary.txt" ]] && cat "$ROOT/output/summary.txt" || printf 'Outputs: not generated\n'
}

run_lab(){
  require_marker

  awk -F',' -v OFS=',' '
    NR==1 { print "treatment_id,purpose,decision,reasons"; next }
    {
      decision="READY"; reasons="PURPOSE+PEOPLE+DATA+BASIS+RECIPIENTS+RETENTION+OWNER"
      if($2=="" || $2=="unknown") { decision="BLOCK_PURPOSE"; reasons="PURPOSE_MISSING" }
      else if($5=="" || $5=="unknown") { decision="ACTION_REQUIRED"; reasons="LEGAL_BASIS_TO_CONFIRM" }
      else if($7=="" || $7=="unlimited") { decision="ACTION_REQUIRED"; reasons="RETENTION_NOT_BOUNDED" }
      else if($9=="" || $9=="unknown") { decision="ACTION_REQUIRED"; reasons="OWNER_MISSING" }
      print $1,$2,decision,reasons
    }
  ' "$ROOT/input/treatments.csv" > "$ROOT/output/treatment-review.csv"

  awk -F',' -v OFS=',' '
    NR==1 { print "case_id,decision,reasons"; next }
    {
      if($8=="READY") print $1,"READY","LIFECYCLE_CONTROLS_PRESENT"
      else if($8=="BLOCK_DESIGN") print $1,"BLOCK_DESIGN","PURPOSE_AND_CONTROLS_MISSING"
      else {
        reasons=""
        if($3!="yes") reasons=reasons "MINIMIZATION;"
        if($4!="yes") reasons=reasons "TRANSPARENCY;"
        if($5!="yes") reasons=reasons "RIGHTS_PROCESS;"
        if($6!="yes") reasons=reasons "RETENTION;"
        if($7!="yes") reasons=reasons "SECURITY;"
        print $1,"ACTION_REQUIRED",reasons
      }
    }
  ' "$ROOT/input/lifecycle.csv" > "$ROOT/output/lifecycle-review.csv"

  awk -F',' -v OFS=',' '
    NR==1 { print "audience,decision,reasons"; next }
    {
      decision="READY"; reasons="RULE+EXERCISE+EVIDENCE"
      if($3=="" || $4=="" || $5=="") { decision="ACTION_REQUIRED"; reasons="RULE_EXERCISE_OR_EVIDENCE_MISSING" }
      print $1,decision,reasons
    }
  ' "$ROOT/input/awareness.csv" > "$ROOT/output/awareness-review.csv"

  awk -F',' -v OFS=',' '
    NR==1 { print "asset_id,asset_type,decision,reasons"; next }
    {
      decision="READY"; reasons="OWNER+MFA+RECOVERY+DEPENDENCY"
      if($7=="BLOCK_RECOVERY") { decision="BLOCK_RECOVERY"; reasons="NO_OWNER+WEAK_RECOVERY" }
      else if($7=="ACTION_REQUIRED") { decision="ACTION_REQUIRED"; reasons="CONTROL_OR_RECOVERY_REVIEW_REQUIRED" }
      else if($3=="unknown" || $5=="personal_mailbox") { decision="ACTION_REQUIRED"; reasons="OWNERSHIP_OR_RECOVERY_WEAK" }
      print $1,$2,decision,reasons
    }
  ' "$ROOT/input/identity-assets.csv" > "$ROOT/output/identity-review.csv"

  awk -F',' -v OFS=',' '
    NR==1 { print "evidence_id,need,decision,technical_claim,limit"; next }
    {
      decision="SUITABLE_FOR_STATED_NEED"; claim=$7; limit="TECHNICAL_RESULT_NOT_COMPLETE_LEGAL_CONCLUSION"
      if($7=="INSUFFICIENT_CONTEXT") { decision="INSUFFICIENT"; claim="HASH_OR_SCREENSHOT_DOES_NOT_PROVE_AUTHOR_TIME_OR_COMPLETE_CASE"; limit="ADDITIONAL_CONTEXT_AND_GOVERNANCE_REQUIRED" }
      print $1,$2,decision,claim,limit
    }
  ' "$ROOT/input/evidence-needs.csv" > "$ROOT/output/evidence-review.csv"

  treatment_actions=$(awk -F',' 'NR>1&&$3!="READY"{c++}END{print c+0}' "$ROOT/output/treatment-review.csv")
  lifecycle_actions=$(awk -F',' 'NR>1&&$2!="READY"{c++}END{print c+0}' "$ROOT/output/lifecycle-review.csv")
  identity_actions=$(awk -F',' 'NR>1&&$3!="READY"{c++}END{print c+0}' "$ROOT/output/identity-review.csv")
  evidence_actions=$(awk -F',' 'NR>1&&$3=="INSUFFICIENT"{c++}END{print c+0}' "$ROOT/output/evidence-review.csv")

  cat > "$ROOT/output/summary.txt" <<EOF
BTS_BLOC3_DATA_IDENTITY_EVIDENCE_READY_WITH_ACTIONS
TREATMENT_ACTIONS=$treatment_actions
LIFECYCLE_ACTIONS=$lifecycle_actions
IDENTITY_ACTIONS=$identity_actions
EVIDENCE_ACTIONS=$evidence_actions
SYNTHETIC_ONLY=yes
LEGAL_CONCLUSION=no
EOF

  (cd "$ROOT" && sha256sum input/* > evidence/sources-after.sha256)
  cmp "$ROOT/evidence/sources-before.sha256" "$ROOT/evidence/sources-after.sha256" >/dev/null || fail "input fixtures changed"
  printf 'BTS data/identity/evidence review generated.\n'
}

validate_lab(){
  require_marker
  [[ "$(rows "$ROOT/input/treatments.csv")" -eq 4 ]] || fail "unexpected treatment count"
  [[ "$(rows "$ROOT/input/lifecycle.csv")" -eq 5 ]] || fail "unexpected lifecycle count"
  [[ "$(rows "$ROOT/input/awareness.csv")" -eq 4 ]] || fail "unexpected awareness count"
  [[ "$(rows "$ROOT/input/identity-assets.csv")" -eq 6 ]] || fail "unexpected identity count"
  [[ "$(rows "$ROOT/input/evidence-needs.csv")" -eq 5 ]] || fail "unexpected evidence count"
  [[ -f "$ROOT/output/summary.txt" ]] || fail "run action first"
  grep -Fq 'BTS_BLOC3_DATA_IDENTITY_EVIDENCE_READY_WITH_ACTIONS' "$ROOT/output/summary.txt"
  grep -Fq 'SYNTHETIC_ONLY=yes' "$ROOT/output/summary.txt"
  grep -Fq 'LEGAL_CONCLUSION=no' "$ROOT/output/summary.txt"
  grep -Fq 'TRT-004' "$ROOT/output/treatment-review.csv"
  grep -Fq 'BLOCK_RECOVERY' "$ROOT/output/identity-review.csv"
  grep -Fq 'INSUFFICIENT' "$ROOT/output/evidence-review.csv"
  cmp "$ROOT/evidence/sources-before.sha256" "$ROOT/evidence/sources-after.sha256" >/dev/null || fail "fixture integrity mismatch"
  printf 'BTS Bloc 3 synthetic lab validation: PASS\n'
}

reset_lab(){
  safe_root
  [[ -e "$ROOT" ]] || exit 0
  require_marker
  rm -rf "$ROOT"
  printf 'BTS data/identity/evidence lab removed: %s\n' "$ROOT"
}

case "$ACTION" in
  setup) setup_lab ;;
  status) status_lab ;;
  run) run_lab ;;
  validate) validate_lab ;;
  reset) reset_lab ;;
  *) fail "usage: $0 {setup|status|run|validate|reset} [lab-root]" ;;
esac
