#!/usr/bin/env python3
"""Secure AI inference pipeline control checklist generator.

This script creates a concise, vendor-neutral security checklist for reviewing
an AI model inference pipeline before production use.

It is intentionally non-destructive and does not contact external systems.

Usage examples:
    python secure_inference_controls.py
    python secure_inference_controls.py --output inference-controls-checklist.txt
    python secure_inference_controls.py --format markdown
"""

from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path
from textwrap import dedent


CHECKLIST_ITEMS = [
    {
        "section": "Identity and access control",
        "items": [
            "Authenticate every caller to the inference entry point.",
            "Authorize access by model, route, tenant, or request context.",
            "Separate human access from machine-to-machine access.",
            "Use least-privilege service identities for the model runtime.",
            "Review and rotate permissions for secrets, queues, databases, and feature stores.",
        ],
    },
    {
        "section": "Network and runtime isolation",
        "items": [
            "Restrict inbound traffic to approved clients, gateways, or service meshes.",
            "Restrict outbound traffic to only required internal dependencies.",
            "Run the model server in a minimally privileged container or process.",
            "Prevent the inference service from becoming a pivot into unrelated systems.",
            "Use separate environments or namespaces for non-production and production traffic.",
        ],
    },
    {
        "section": "Input validation and schema enforcement",
        "items": [
            "Validate request structure, types, and required fields before enrichment.",
            "Apply payload size limits and request timeout limits.",
            "Canonicalize data before parsing when applicable.",
            "Reject malformed, unexpected, or oversized inputs safely.",
            "Test parser behavior with adversarial, nested, and edge-case payloads.",
        ],
    },
    {
        "section": "Feature access control",
        "items": [
            "Authorize every feature lookup using caller identity and request context.",
            "Log feature access with enough detail for audit and incident review.",
            "Do not expose features that the caller should not be able to infer.",
            "Separate public, tenant-scoped, and internal feature sets.",
            "Verify cache layers enforce the same access rules as the source store.",
        ],
    },
    {
        "section": "Output protection and integrity",
        "items": [
            "Return only the minimum response needed for the application.",
            "Suppress or reduce sensitive confidence values, scores, or explanations where appropriate.",
            "Validate response shape before downstream consumption.",
            "Use integrity checks if the result passes through intermediate services.",
            "Prevent logging of raw outputs when they contain sensitive inferences.",
        ],
    },
    {
        "section": "Telemetry, monitoring, and rollback",
        "items": [
            "Track request volume, latency, error rates, and schema violations.",
            "Monitor feature lookup failures and authorization denials.",
            "Record model version, deployment time, and routing changes.",
            "Alert on abnormal input patterns, traffic spikes, and unusual output behavior.",
            "Define rollback criteria and verify you can revert to a safe version quickly.",
        ],
    },
]


def render_markdown() -> str:
    lines = [
        "# Secure AI Inference Pipeline Control Checklist",
        "",
        "Use this checklist to review an AI model inference pipeline before production use.",
        "",
        "## Control areas",
        "",
    ]

    for section in CHECKLIST_ITEMS:
        lines.append(f"### {section['section']}")
        lines.append("")
        for item in section["items"]:
            lines.append(f"- [ ] {item}")
        lines.append("")

    lines.extend(
        [
            "## Acceptance questions",
            "",
            "- Who is allowed to call this endpoint?",
            "- What input is acceptable, and how is it validated?",
            "- What systems can this service reach if it is compromised?",
            "- What is logged, retained, and redacted?",
            "- How do we roll back if behavior becomes unsafe or unstable?",
            "",
            "## Review note",
            "",
            "Treat the inference path as a security-sensitive production service, not just a model API.",
        ]
    )
    return "\n".join(lines)


def render_text() -> str:
    lines = ["Secure AI Inference Pipeline Control Checklist", ""]
    for section in CHECKLIST_ITEMS:
        lines.append(section["section"])
        for item in section["items"]:
            lines.append(f"- {item}")
        lines.append("")
    return "\n".join(lines).rstrip() + "\n"


def render_json() -> str:
    return json.dumps(CHECKLIST_ITEMS, indent=2)


def validate_output_path(path: str) -> Path:
    p = Path(path)
    if p.exists() and p.is_dir():
        raise ValueError("Output path must be a file, not a directory.")
    if not p.suffix:
        raise ValueError("Output path must include a file extension.")
    return p


def main(argv: list[str]) -> int:
    parser = argparse.ArgumentParser(
        description="Generate a security checklist for AI inference pipelines."
    )
    parser.add_argument(
        "--format",
        choices=("markdown", "text", "json"),
        default="markdown",
        help="Output format to generate.",
    )
    parser.add_argument(
        "--output",
        help="Write output to a file instead of stdout.",
    )
    args = parser.parse_args(argv)

    if args.format == "markdown":
        content = render_markdown()
    elif args.format == "text":
        content = render_text()
    else:
        content = render_json()

    if args.output:
        try:
            output_path = validate_output_path(args.output)
        except ValueError as exc:
            print(f"Error: {exc}", file=sys.stderr)
            return 2
        output_path.write_text(content, encoding="utf-8")
        print(f"Wrote {output_path}")
    else:
        print(content)

    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))