"""Starter kit generator — emits policy JSON, sample report, GH Actions YAML, README."""

from __future__ import annotations

from pathlib import Path

# ── Policy JSON ──────────────────────────────────────────────────────────────

SOC2_POLICY_JSON = """{
  "zero_tolerance": ["AP101", "AP201"],
  "warn": ["AP001", "AP002", "AP003", "AP004", "AP007", "AP008"],
  "fail_on": "high"
}
"""

ISO27001_POLICY_JSON = """{
  "zero_tolerance": ["AP101", "AP201", "AP102"],
  "warn": ["AP001", "AP002", "AP003", "AP004", "AP007", "AP008"],
  "fail_on": "high"
}
"""

# ── GitHub Actions ────────────────────────────────────────────────────────────

PR_GATE_YAML = """name: ApiPosture PR Gate

on:
  pull_request:
    branches: [main, master]

jobs:
  apiposture-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install ApiPosturePro
        run: pip install apiposture-pro

      - name: Run ApiPosture scan with policy enforcement
        env:
          APIPOSTURE_LICENSE_KEY: ${{ secrets.APIPOSTURE_LICENSE_KEY }}
        run: |
          apiposture-pro scan . --with-history
        # Exit code 1 blocks merge on zero-tolerance violations
"""

WEEKLY_REPORT_YAML = """name: ApiPosture Weekly Compliance Report

on:
  schedule:
    - cron: "0 9 * * 1"  # Every Monday at 09:00 UTC
  workflow_dispatch:

jobs:
  compliance-report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install ApiPosturePro
        run: pip install apiposture-pro

      - name: Run scan and save to history
        env:
          APIPOSTURE_LICENSE_KEY: ${{ secrets.APIPOSTURE_LICENSE_KEY }}
        run: |
          apiposture-pro scan . --with-history --framework all

      - name: Generate compliance report
        env:
          APIPOSTURE_LICENSE_KEY: ${{ secrets.APIPOSTURE_LICENSE_KEY }}
        run: |
          apiposture-pro compliance report . \\
            --framework all \\
            --output both \\
            --operator "GitHub Actions"

      - name: Upload report artifacts
        uses: actions/upload-artifact@v4
        with:
          name: compliance-report-${{ github.run_number }}
          path: |
            compliance-report-*.html
            compliance-report-*.pdf
"""

# ── README ────────────────────────────────────────────────────────────────────

SOC2_README = """# ApiPosture SOC 2 Starter Kit

This starter kit helps you prepare API security evidence for a SOC 2 audit.

## What's Included

- `.apiposture-policy.json` — Zero-tolerance rules for SOC 2
- `sample-report.html` — Sample compliance report
- `github-actions/apiposture-pr-gate.yml` — Block PRs with critical findings
- `github-actions/apiposture-weekly-report.yml` — Weekly compliance reports

## Setup

1. Copy `.apiposture-policy.json` to your project root.
2. Add `APIPOSTURE_LICENSE_KEY` to your GitHub repository secrets.
3. Copy the GitHub Actions files to `.github/workflows/`.

## 10 Most Common Findings

| Rule | Description | SOC 2 Control | How to Fix |
|------|-------------|---------------|------------|
| AP001 | Endpoint missing authentication | CC6.1 | Add `@login_required` / `Depends(get_current_user)` |
| AP002 | Missing role-based access control | CC6.3 | Add role check before sensitive operations |
| AP003 | Inconsistent auth scheme | CC6.6 | Apply uniform auth middleware to resource group |
| AP004 | Auth entry point not marked public | CC6.1 | Add explicit `allow_anonymous` decorator |
| AP005 | Privilege escalation risk | CC6.3 | Validate caller role before elevation |
| AP006 | Admin endpoint without admin guard | CC6.3 | Restrict with admin-role middleware |
| AP007 | Sensitive keyword in route name | CC6.1 | Add auth middleware to this endpoint |
| AP008 | Public endpoint with sensitive operation | CC6.6 | Require authentication |
| AP101 | Broken access control | CC6.1 | Enforce authorization on every handler |
| AP201 | Hardcoded secret detected | CC6.7 | Move to environment variable or secrets manager |

## Evidence Package for Auditors

Run weekly scans and export reports:

```bash
apiposture-pro compliance report . --framework soc2 --output both
```

Provide the generated PDF to your auditor as evidence of continuous security monitoring.
"""

ISO27001_README = """# ApiPosture ISO 27001 Starter Kit

This starter kit helps you prepare API security evidence for an ISO 27001 audit.

## What's Included

- `.apiposture-policy.json` — Zero-tolerance rules for ISO 27001
- `sample-report.html` — Sample compliance report
- `github-actions/apiposture-pr-gate.yml` — Block PRs with critical findings
- `github-actions/apiposture-weekly-report.yml` — Weekly compliance reports

## Setup

1. Copy `.apiposture-policy.json` to your project root.
2. Add `APIPOSTURE_LICENSE_KEY` to your GitHub repository secrets.
3. Copy the GitHub Actions files to `.github/workflows/`.

## 10 Most Common Findings

| Rule | Description | ISO Control | How to Fix |
|------|-------------|-------------|------------|
| AP001 | Endpoint missing authentication | A.14.1.2 | Add authentication middleware |
| AP002 | Missing role-based access control | A.14.1.2 | Add role check before sensitive operations |
| AP003 | Inconsistent auth scheme | A.14.2.5 | Unify authentication pattern |
| AP004 | Auth entry point not marked public | A.14.1.2 | Add explicit public annotation |
| AP005 | Privilege escalation risk | A.14.1.2 | Validate caller role before elevation |
| AP006 | Admin endpoint without admin guard | A.14.1.2 | Add admin-role middleware |
| AP007 | Sensitive keyword in route name | A.14.2.1 | Add auth middleware |
| AP008 | Public endpoint with sensitive operation | A.14.1.2 | Require authentication |
| AP101 | Broken access control | A.14.1.2 | Enforce authorization on every handler |
| AP102 | Weak/missing encryption | A.14.1.3 | Enforce TLS 1.2+, strong cipher suites |

## Evidence Package for Auditors

Run weekly scans and export reports:

```bash
apiposture-pro compliance report . --framework iso27001 --output both
```

Provide the generated PDF to your auditor as evidence of Annex A control implementation.
"""

# ── Sample HTML Report ────────────────────────────────────────────────────────

SAMPLE_REPORT_HTML = """<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ApiPosture Sample Compliance Report</title>
  <style>
    body {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
    h1 {{ color: #2c3e50; }}
    h2 {{ color: #34495e; border-bottom: 1px solid #ccc; padding-bottom: 6px; }}
    .disclaimer {{ background: #fff3cd; border: 1px solid #ffc107; padding: 12px; border-radius: 4px; margin-bottom: 20px; font-size: 0.9em; }}
    .callout {{ background: #e8f4fd; border-left: 4px solid #3498db; padding: 12px; margin: 16px 0; font-size: 0.9em; }}
    .score-box {{ display: inline-block; padding: 12px 24px; border-radius: 8px; background: #ecf0f1; margin-bottom: 20px; }}
    .score-num {{ font-size: 2.5em; font-weight: bold; color: #2c3e50; }}
    table {{ border-collapse: collapse; width: 100%; font-size: 0.9em; }}
    th {{ background: #2c3e50; color: white; padding: 8px; text-align: left; }}
    td {{ border: 1px solid #ddd; padding: 8px; vertical-align: top; }}
    tr:nth-child(even) {{ background: #f9f9f9; }}
    .footer {{ margin-top: 30px; font-size: 0.8em; color: #7f8c8d; border-top: 1px solid #eee; padding-top: 10px; }}
  </style>
</head>
<body>
  <h1>ApiPosture Compliance Report (Sample)</h1>
  <div class="disclaimer">
    Scope: API authorization and security misconfiguration controls.
    This report covers a subset of {framework} controls.
    See your audit firm for full control mapping guidance.
  </div>
  <div class="callout">
    <strong>Auditor Note:</strong> This is a sample report showing the structure of evidence
    produced by ApiPosturePro. Real reports are generated from live scans of your codebase.
  </div>

  <h2>Scan Summary</h2>
  <p><strong>Framework:</strong> {framework_display}</p>
  <p><strong>Scan ID:</strong> sample-001</p>
  <p><strong>Timestamp:</strong> 2026-04-01 09:00:00 UTC</p>
  <p><strong>Scanned Path:</strong> /app/api</p>
  <p><strong>Operator:</strong> Security Team</p>
  <p><strong>Total Endpoints:</strong> 42</p>
  <p><strong>Total Findings:</strong> 3</p>

  <h2>Compliance Score</h2>
  <div class="score-box">
    <div class="score-num">40/100</div>
    <div>Trend: ↑ UP</div>
  </div>
  <p><strong>Penalty Breakdown:</strong>
    Critical: 30 pts &nbsp;|&nbsp; High: 20 pts &nbsp;|&nbsp; Medium: 10 pts &nbsp;|&nbsp; Low: 0 pts
  </p>
  <div class="callout">
    <strong>Auditor Note:</strong> The compliance score reflects the cumulative penalty from
    findings weighted by severity. A score of 100 means zero findings. Trend shows change
    vs. the previous scan of this path.
  </div>

  <h2>Findings (3)</h2>
  <table>
    <tr>
      <th>Severity</th><th>Rule</th><th>Message</th><th>Location</th><th>Controls</th><th>Remediation</th>
    </tr>
    <tr>
      <td><span style="color:#c0392b;font-weight:bold">CRITICAL</span></td>
      <td>AP101</td>
      <td>Broken access control: handler has no authorization check</td>
      <td>api/users.py:42</td>
      <td>SOC2 CC6.1, ISO A.14.1.2</td>
      <td>Broken access control. Enforce authorization on every handler.</td>
    </tr>
    <tr>
      <td><span style="color:#e74c3c;font-weight:bold">HIGH</span></td>
      <td>AP001</td>
      <td>Endpoint /api/data has no authentication</td>
      <td>api/data.py:15</td>
      <td>SOC2 CC6.1, ISO A.14.1.2</td>
      <td>Ensure all endpoints require authentication.</td>
    </tr>
    <tr>
      <td><span style="color:#e67e22;font-weight:bold">MEDIUM</span></td>
      <td>AP007</td>
      <td>Sensitive keyword 'secret' in route without auth</td>
      <td>api/config.py:8</td>
      <td>SOC2 CC6.1, ISO A.14.2.1</td>
      <td>Sensitive route exposed without protection. Add auth middleware.</td>
    </tr>
  </table>
  <div class="callout">
    <strong>Auditor Note:</strong> Each finding maps to specific SOC 2 / ISO 27001 controls.
    The remediation guidance shows the concrete code change required.
  </div>

  <div class="footer">
    <p>Checksum (SHA-256): [computed at scan time]</p>
    <p>Generated by ApiPosturePro — Sample Report</p>
  </div>
</body>
</html>"""


def emit_starter_kit(framework: str, output_dir: Path) -> list[Path]:
    """
    Emit all starter kit files to output_dir.

    Args:
        framework: "soc2" or "iso27001"
        output_dir: Directory to write files to (created if missing)

    Returns:
        List of created file paths.
    """
    output_dir.mkdir(parents=True, exist_ok=True)
    (output_dir / "github-actions").mkdir(exist_ok=True)

    created: list[Path] = []

    # Policy JSON
    policy_json = SOC2_POLICY_JSON if framework == "soc2" else ISO27001_POLICY_JSON
    p = output_dir / ".apiposture-policy.json"
    p.write_text(policy_json, encoding="utf-8")
    created.append(p)

    # Sample report HTML
    framework_display = "SOC 2" if framework == "soc2" else "ISO 27001"
    sample_html = SAMPLE_REPORT_HTML.format(
        framework=framework_display, framework_display=framework_display
    )
    p = output_dir / "sample-report.html"
    p.write_text(sample_html, encoding="utf-8")
    created.append(p)

    # GitHub Actions — PR gate
    p = output_dir / "github-actions" / "apiposture-pr-gate.yml"
    p.write_text(PR_GATE_YAML, encoding="utf-8")
    created.append(p)

    # GitHub Actions — weekly report
    p = output_dir / "github-actions" / "apiposture-weekly-report.yml"
    p.write_text(WEEKLY_REPORT_YAML, encoding="utf-8")
    created.append(p)

    # README
    readme_text = SOC2_README if framework == "soc2" else ISO27001_README
    p = output_dir / "README.md"
    p.write_text(readme_text, encoding="utf-8")
    created.append(p)

    return created
