#!/bin/sh
# TitanShield Security Scanner - One command CLI
# Usage: curl -sL https://titanshield.tech/cli.sh | sh -s -- --token YOUR_TOKEN app.apk
#    or: ./titanshield --token YOUR_TOKEN app.apk
#    or: ./titanshield --token YOUR_TOKEN --type dast app.apk
#
# Exit codes: 0 = pass, 1 = critical vulns found, 2 = scan error

set -e

TITANSHIELD_URL="${TITANSHIELD_URL:-https://titanshield.tech}"
TOKEN=""
FILE=""
TYPE="sast"
MODE="quick"
FAIL_ON="critical"
FORMAT="text"
OUTPUT=""
QUIET=0

# Parse args
while [ $# -gt 0 ]; do
  case "$1" in
    --token|-t) TOKEN="$2"; shift 2;;
    --type) TYPE="$2"; shift 2;;
    --mode) MODE="$2"; shift 2;;
    --fail-on) FAIL_ON="$2"; shift 2;;
    --format|-f) FORMAT="$2"; shift 2;;
    --output|-o) OUTPUT="$2"; shift 2;;
    --quiet|-q) QUIET=1; shift;;
    --url) TITANSHIELD_URL="$2"; shift 2;;
    --help|-h)
      echo "TitanShield Security Scanner"
      echo ""
      echo "Usage: titanshield [options] <file.apk|file.ipa>"
      echo ""
      echo "Options:"
      echo "  --token, -t TOKEN    API token (required, or set TITANSHIELD_API_TOKEN)"
      echo "  --type TYPE          sast or dast (default: sast)"
      echo "  --mode MODE          quick, full, or deep (default: quick)"
      echo "  --fail-on SEVERITY   critical, high, medium, low (default: critical)"
      echo "  --format, -f FORMAT  text, json, or sarif (default: text)"
      echo "  --output, -o FILE    Write results to file"
      echo "  --quiet, -q          Minimal output"
      echo "  --help, -h           Show this help"
      echo ""
      echo "Examples:"
      echo "  titanshield --token xxx app.apk"
      echo "  titanshield --token xxx --type dast --mode full app.ipa"
      echo "  titanshield --token xxx --format sarif --output results.sarif app.apk"
      echo ""
      echo "CI/CD:"
      echo "  titanshield --token \$TOKEN --fail-on high app.apk || exit 1"
      exit 0;;
    -*) echo "Unknown option: $1"; exit 2;;
    *) FILE="$1"; shift;;
  esac
done

# Resolve token
TOKEN="${TOKEN:-$TITANSHIELD_API_TOKEN}"
if [ -z "$TOKEN" ]; then
  echo "Error: No API token. Use --token or set TITANSHIELD_API_TOKEN" >&2
  exit 2
fi

if [ -z "$FILE" ]; then
  echo "Error: No file specified. Usage: titanshield --token TOKEN app.apk" >&2
  exit 2
fi

if [ ! -f "$FILE" ]; then
  echo "Error: File not found: $FILE" >&2
  exit 2
fi

# Detect platform from extension
case "$FILE" in
  *.apk|*.aab) PLATFORM="android";;
  *.ipa) PLATFORM="ios";;
  *) echo "Error: Unsupported file type. Use .apk, .aab, or .ipa" >&2; exit 2;;
esac

SIZE=$(wc -c < "$FILE" | tr -d ' ')
[ "$QUIET" = 0 ] && echo "TitanShield | $PLATFORM $TYPE | $(basename "$FILE") ($(echo "$SIZE/1024/1024" | bc 2>/dev/null || echo "$SIZE bytes"))"

# Upload
[ "$QUIET" = 0 ] && printf "Uploading..."
RESPONSE=$(curl -s -X POST "$TITANSHIELD_URL/run_analysis" \
  -H "X-API-Token: $TOKEN" \
  -F "platform=$PLATFORM" \
  -F "type=$TYPE" \
  -F "mode=$MODE" \
  -F "input_file=@$FILE")

# Check for errors
ERROR=$(echo "$RESPONSE" | grep -o '"error":"[^"]*"' | head -1 | sed 's/"error":"//;s/"//')
if [ -n "$ERROR" ]; then
  echo " FAILED"
  echo "Error: $ERROR" >&2
  exit 2
fi

AID=$(echo "$RESPONSE" | grep -o '"analysis_id":[0-9]*' | head -1 | sed 's/"analysis_id"://')
if [ -z "$AID" ]; then
  echo " FAILED"
  echo "Error: No analysis_id in response" >&2
  exit 2
fi
[ "$QUIET" = 0 ] && echo " OK (ID: $AID)"

# Poll
[ "$QUIET" = 0 ] && printf "Scanning"
ATTEMPTS=0
MAX_ATTEMPTS=120
while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do
  ATTEMPTS=$((ATTEMPTS + 1))
  sleep 10

  STATUS_RESP=$(curl -s "$TITANSHIELD_URL/api/analysis/$AID/status" \
    -H "X-API-Token: $TOKEN")

  # Extract status: check for known values (avoids matching nested "status" in vulns)
  STATUS="unknown"
  case "$STATUS_RESP" in
    *'"status":"done"'*) STATUS="done";;
    *'"status":"completed"'*) STATUS="completed";;
    *'"status":"running"'*) STATUS="running";;
    *'"status":"queued"'*) STATUS="queued";;
    *'"status":"failed"'*) STATUS="failed";;
  esac

  if [ "$STATUS" = "done" ] || [ "$STATUS" = "completed" ]; then
    [ "$QUIET" = 0 ] && echo " done"
    break
  elif [ "$STATUS" = "failed" ]; then
    [ "$QUIET" = 0 ] && echo " FAILED"
    echo "Error: Scan failed" >&2
    exit 2
  fi
  [ "$QUIET" = 0 ] && printf "."
done

if [ "$STATUS" != "done" ] && [ "$STATUS" != "completed" ]; then
  echo " TIMEOUT" >&2
  exit 2
fi

# Extract counts (portable, no jq needed)
get_val() {
  echo "$STATUS_RESP" | grep -o "\"$1\":[0-9]*" | head -1 | sed "s/\"$1\"://"
}

VULNS=$(get_val "vulnerabilities_count")
CRITICAL=$(get_val "Critical")
HIGH=$(get_val "High")
MEDIUM=$(get_val "Medium")
LOW=$(get_val "Low")

VULNS=${VULNS:-0}
CRITICAL=${CRITICAL:-0}
HIGH=${HIGH:-0}
MEDIUM=${MEDIUM:-0}
LOW=${LOW:-0}

# Output
if [ "$FORMAT" = "json" ] || [ "$FORMAT" = "sarif" ]; then
  # Download report in requested format
  DL_FORMAT="json"
  [ "$FORMAT" = "sarif" ] && DL_FORMAT="sarif"
  REPORT=$(curl -sL "$TITANSHIELD_URL/api/analysis/$AID/download/$DL_FORMAT" \
    -H "X-API-Token: $TOKEN")
  if [ -n "$OUTPUT" ]; then
    echo "$REPORT" > "$OUTPUT"
    [ "$QUIET" = 0 ] && echo "Report saved to $OUTPUT"
  else
    echo "$REPORT"
  fi
else
  # Text output
  echo ""
  echo "  Vulnerabilities: $VULNS"
  echo "  Critical: $CRITICAL | High: $HIGH | Medium: $MEDIUM | Low: $LOW"
  echo "  Report: $TITANSHIELD_URL/analysis/s/$AID"
  echo ""
fi

# Security gate
FAIL=0
case "$FAIL_ON" in
  critical) [ "$CRITICAL" -gt 0 ] && FAIL=1;;
  high)     [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ] && FAIL=1;;
  medium)   [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ] || [ "$MEDIUM" -gt 0 ] && FAIL=1;;
  low)      [ "$VULNS" -gt 0 ] && FAIL=1;;
esac

if [ "$FAIL" = 1 ]; then
  [ "$QUIET" = 0 ] && echo "SECURITY GATE: FAILED ($FAIL_ON+ vulnerabilities found)"
  exit 1
fi

[ "$QUIET" = 0 ] && echo "SECURITY GATE: PASSED"
exit 0
