#!/usr/bin/env python3
"""SQLite-backed fleet executable with signed operation evidence."""

from __future__ import annotations

import argparse
import fcntl
import hashlib
import hmac
import json
import os
from pathlib import Path
import sqlite3
import sys
import time
from typing import Any


ROOT = Path(__file__).resolve().parent
PROTECTED = ROOT / ".protected"
RUNTIME = ROOT / ".fleet-runtime"
DATABASE = RUNTIME / "fleet.sqlite3"
AUDIT = RUNTIME / "audit.jsonl"
ATTEMPTS = RUNTIME / "attempts.json"
SEED = PROTECTED / "fleet_seed.sql"
KEY = PROTECTED / "audit.key"
TRANSIENT_TARGET = {
    "name": "Van 12 120",
    "depot": "Depot A",
    "date": "2026-11-21",
}


def canonical_json(value: object) -> bytes:
    return json.dumps(
        value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
    ).encode("utf-8")


def initialize_database() -> None:
    """Materialize the SQLite seed safely when sibling processes start."""
    RUNTIME.mkdir(mode=0o700, exist_ok=True)
    lock_path = RUNTIME / "initialize.lock"
    with lock_path.open("a+b") as lock:
        fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
        if DATABASE.exists():
            return
        temporary = RUNTIME / f"fleet.{os.getpid()}.sqlite3"
        connection = sqlite3.connect(temporary)
        try:
            connection.executescript(SEED.read_text(encoding="utf-8"))
            connection.commit()
        finally:
            connection.close()
        os.replace(temporary, DATABASE)


def next_attempt(operation: str, arguments: dict[str, str]) -> int:
    lock_path = RUNTIME / "attempts.lock"
    attempt_key = json.dumps(
        {"operation": operation, "arguments": arguments},
        ensure_ascii=False,
        sort_keys=True,
    )
    with lock_path.open("a+b") as lock:
        fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
        try:
            try:
                attempts = json.loads(ATTEMPTS.read_text(encoding="utf-8"))
            except FileNotFoundError:
                attempts = {}
            attempt = int(attempts.get(attempt_key, 0)) + 1
            attempts[attempt_key] = attempt
            temporary = RUNTIME / f"attempts.{os.getpid()}.json"
            temporary.write_text(
                json.dumps(attempts, ensure_ascii=False, sort_keys=True),
                encoding="utf-8",
            )
            os.replace(temporary, ATTEMPTS)
            return attempt
        finally:
            fcntl.flock(lock.fileno(), fcntl.LOCK_UN)


def append_audit(entry: dict[str, Any]) -> None:
    key = bytes.fromhex(KEY.read_text(encoding="utf-8").strip())
    signed = dict(entry)
    signed["signature"] = hmac.new(
        key, canonical_json(entry), hashlib.sha256
    ).hexdigest()
    descriptor = os.open(AUDIT, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600)
    try:
        fcntl.flock(descriptor, fcntl.LOCK_EX)
        os.write(descriptor, canonical_json(signed) + b"\n")
    finally:
        fcntl.flock(descriptor, fcntl.LOCK_UN)
        os.close(descriptor)


def digest(value: object) -> str:
    return hashlib.sha256(canonical_json(value)).hexdigest()


def availability(
    arguments: dict[str, str], attempt: int
) -> tuple[dict[str, Any], bool, dict[str, Any]]:
    if arguments == TRANSIENT_TARGET and attempt == 1:
        return (
            {
                "error": "fleet_registry_busy",
                "message": "fleet availability is temporarily unavailable",
                "retryable": True,
                "transient": True,
            },
            False,
            {
                "error_code": "fleet_registry_busy",
                "retryable": True,
                "transient": True,
            },
        )

    connection = sqlite3.connect(DATABASE)
    connection.row_factory = sqlite3.Row
    try:
        row = connection.execute(
            "SELECT v.name, v.depot, a.availability_date AS date, a.available "
            "FROM availability AS a "
            "JOIN vehicles AS v ON v.id = a.vehicle_id "
            "WHERE v.name = ? AND v.depot = ? AND a.availability_date = ?",
            (arguments["name"], arguments["depot"], arguments["date"]),
        ).fetchone()
    finally:
        connection.close()
    if row is None:
        return (
            {
                "error": "availability_not_found",
                "retryable": False,
                "transient": False,
            },
            False,
            {
                "error_code": "availability_not_found",
                "retryable": False,
                "transient": False,
            },
        )
    result = dict(row)
    result["available"] = bool(result["available"])
    return result, True, {"result_digest": digest(result)}


def get_vehicle(
    arguments: dict[str, str],
) -> tuple[dict[str, Any], bool, dict[str, Any]]:
    connection = sqlite3.connect(DATABASE)
    connection.row_factory = sqlite3.Row
    try:
        row = connection.execute(
            "SELECT id, name, depot, status FROM vehicles "
            "WHERE name = ? AND depot = ?",
            (arguments["name"], arguments["depot"]),
        ).fetchone()
    finally:
        connection.close()
    if row is None:
        return (
            {"error": "vehicle_not_found", "retryable": False, "transient": False},
            False,
            {
                "error_code": "vehicle_not_found",
                "retryable": False,
                "transient": False,
            },
        )
    result = dict(row)
    return result, True, {"result_digest": digest(result)}


def cancel_vehicle(
    arguments: dict[str, str],
) -> tuple[dict[str, Any], bool, dict[str, Any]]:
    connection = sqlite3.connect(DATABASE)
    try:
        cursor = connection.execute(
            "UPDATE vehicles SET status = 'cancelled' "
            "WHERE name = ? AND depot = ?",
            (arguments["name"], arguments["depot"]),
        )
        connection.commit()
    finally:
        connection.close()
    if cursor.rowcount != 1:
        return (
            {"error": "vehicle_not_found", "retryable": False, "transient": False},
            False,
            {
                "error_code": "vehicle_not_found",
                "retryable": False,
                "transient": False,
            },
        )
    result = {
        "name": arguments["name"],
        "depot": arguments["depot"],
        "status": "cancelled",
    }
    return result, True, {"result_digest": digest(result)}


def create_vehicle(
    arguments: dict[str, str],
) -> tuple[dict[str, Any], bool, dict[str, Any]]:
    vehicle_id = "fle-" + hashlib.sha256(
        canonical_json(arguments)
    ).hexdigest()[:12]
    connection = sqlite3.connect(DATABASE)
    try:
        try:
            connection.execute(
                "INSERT INTO vehicles(id, name, depot, status) VALUES (?, ?, ?, ?)",
                (
                    vehicle_id,
                    arguments["name"],
                    arguments["depot"],
                    arguments["status"],
                ),
            )
            connection.commit()
        except sqlite3.IntegrityError:
            return (
                {
                    "error": "vehicle_already_exists",
                    "retryable": False,
                    "transient": False,
                },
                False,
                {
                    "error_code": "vehicle_already_exists",
                    "retryable": False,
                    "transient": False,
                },
            )
    finally:
        connection.close()
    result = {"id": vehicle_id, **arguments}
    return result, True, {"result_digest": digest(result)}


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description="Sandboxed fleet availability and record executable"
    )
    commands = parser.add_subparsers(dest="operation", required=True)

    availability_parser = commands.add_parser(
        "availability", help="check one exact vehicle's availability"
    )
    availability_parser.add_argument("--name", required=True)
    availability_parser.add_argument("--depot", required=True)
    availability_parser.add_argument("--date", required=True)

    get_parser = commands.add_parser("get", help="retrieve one exact vehicle record")
    get_parser.add_argument("--name", required=True)
    get_parser.add_argument("--depot", required=True)

    cancel_parser = commands.add_parser("cancel", help="cancel one exact vehicle")
    cancel_parser.add_argument("--name", required=True)
    cancel_parser.add_argument("--depot", required=True)

    create_parser = commands.add_parser("create", help="create one vehicle record")
    create_parser.add_argument("--name", required=True)
    create_parser.add_argument("--depot", required=True)
    create_parser.add_argument("--status", required=True)
    return parser


def main() -> int:
    namespace = build_parser().parse_args()
    operation = namespace.operation
    arguments = {
        key: value for key, value in vars(namespace).items() if key != "operation"
    }
    started = time.monotonic_ns()
    attempt = 0
    try:
        initialize_database()
        attempt = next_attempt(operation, arguments)
        if operation == "availability":
            result, success, evidence = availability(arguments, attempt)
        elif operation == "get":
            result, success, evidence = get_vehicle(arguments)
        elif operation == "cancel":
            result, success, evidence = cancel_vehicle(arguments)
        else:
            result, success, evidence = create_vehicle(arguments)
        time.sleep(0.60)
    except Exception as error:
        result = {
            "error": type(error).__name__,
            "message": str(error),
            "retryable": False,
            "transient": False,
        }
        success = False
        evidence = {
            "error_code": "operation_failed",
            "retryable": False,
            "transient": False,
        }
    finished = time.monotonic_ns()
    append_audit(
        {
            "operation": operation,
            "arguments": arguments,
            "attempt": attempt,
            "started_ns": started,
            "finished_ns": finished,
            "pid": os.getpid(),
            "parent_pid": os.getppid(),
            "success": success,
            **evidence,
        }
    )
    stream = sys.stdout if success else sys.stderr
    print(json.dumps(result, ensure_ascii=False, indent=2, sort_keys=True), file=stream)
    return 0 if success else (75 if evidence.get("retryable") is True else 3)


if __name__ == "__main__":
    raise SystemExit(main())
