"""
Self-contained evidence package export.

Produces a ZIP that bundles everything needed for independent
verification of attested images:
- Original images
- Attestation records with full signatures
- Chain segment with hash linkage
- Signer's public key
- Standalone verification script
- Human-readable README

The package is verifiable by a standalone script with no SooSeF
installation required — only the `cryptography` pip package.
"""

from __future__ import annotations

import hashlib
import json
import zipfile
from datetime import UTC, datetime
from pathlib import Path


def export_evidence_package(
    image_paths: list[Path],
    storage,
    chain_store,
    public_key_path: Path | None = None,
    output_path: Path | None = None,
    investigation: str | None = None,
) -> Path:
    """Export a self-contained evidence package as a ZIP.

    Args:
        image_paths: Paths to the original image files to include.
        storage: verisoo LocalStorage instance.
        chain_store: ChainStore instance (or None).
        public_key_path: Path to the signer's public key PEM.
        output_path: Output ZIP path (default: auto-generated).
        investigation: Optional investigation label for filtering.

    Returns:
        Path to the created ZIP file.
    """
    from soosef.verisoo.hashing import hash_image

    if output_path is None:
        ts = datetime.now(UTC).strftime("%Y%m%dT%H%M%SZ")
        output_path = Path(f"evidence_{ts}.zip")

    # Collect attestation records for the provided images
    image_records = []
    for img_path in image_paths:
        img_data = img_path.read_bytes()
        sha256 = hashlib.sha256(img_data).hexdigest()

        # Look up attestation records by SHA-256
        records = storage.get_records_by_image_sha256(sha256)
        for record in records:
            rec_data = {
                "filename": img_path.name,
                "sha256": sha256,
                "attestor_fingerprint": record.attestor_fingerprint,
                "timestamp": record.timestamp.isoformat() if record.timestamp else None,
                "signature": record.signature.hex() if record.signature else None,
                "image_hashes": {
                    "sha256": record.image_hashes.sha256,
                    "phash": record.image_hashes.phash,
                    "dhash": getattr(record.image_hashes, "dhash", ""),
                },
                "metadata": record.metadata if hasattr(record, "metadata") else {},
            }
            image_records.append(rec_data)

    # Collect chain records if available
    chain_data = []
    if chain_store is not None:
        from soosef.federation.serialization import compute_record_hash

        try:
            for chain_rec in chain_store:
                chain_data.append({
                    "chain_index": chain_rec.chain_index,
                    "content_hash": chain_rec.content_hash.hex(),
                    "content_type": chain_rec.content_type,
                    "prev_hash": chain_rec.prev_hash.hex(),
                    "record_hash": compute_record_hash(chain_rec).hex(),
                    "signer_pubkey": chain_rec.signer_pubkey.hex(),
                    "signature": chain_rec.signature.hex(),
                    "claimed_ts": chain_rec.claimed_ts,
                    "metadata": chain_rec.metadata,
                })
        except Exception:
            pass

    manifest = {
        "package_version": "1",
        "exported_at": datetime.now(UTC).isoformat(),
        "investigation": investigation,
        "images": [p.name for p in image_paths],
        "attestation_records": image_records,
        "chain_records": chain_data,
        "chain_record_count": len(chain_data),
    }

    readme = f"""SOOSEF EVIDENCE PACKAGE
======================

Exported: {manifest['exported_at']}
Investigation: {investigation or 'N/A'}
Images: {len(image_paths)}
Attestation records: {len(image_records)}
Chain records: {len(chain_data)}

CONTENTS
--------
images/          — Original image files
manifest.json    — Attestation records and chain data
public_key.pem   — Signer's Ed25519 public key
verify.py        — Standalone verification script
README.txt       — This file

VERIFICATION
------------
1. Install Python 3.11+ and the cryptography package:
   pip install cryptography

2. Run the verification script:
   python verify.py

3. The script verifies:
   - Image SHA-256 hashes match attestation records
   - Chain hash linkage is unbroken
   - Ed25519 signatures are valid (if public key is available)

This package is self-contained. No SooSeF installation is required
to verify the evidence.
"""

    verify_script = '''#!/usr/bin/env python3
"""Standalone evidence package verifier."""

import hashlib
import json
import sys
from pathlib import Path

def main():
    here = Path(__file__).parent
    manifest = json.loads((here / "manifest.json").read_text())

    print("SooSeF Evidence Package Verifier")
    print("=" * 40)
    print(f"Exported: {manifest['exported_at']}")
    print(f"Investigation: {manifest.get('investigation', 'N/A')}")
    print()

    errors = 0

    # Verify image hashes
    print("Verifying image hashes...")
    for img_name in manifest.get("images", []):
        img_path = here / "images" / img_name
        if not img_path.exists():
            print(f"  MISSING: {img_name}")
            errors += 1
            continue
        actual_hash = hashlib.sha256(img_path.read_bytes()).hexdigest()
        # Find matching attestation record
        matched = False
        for rec in manifest.get("attestation_records", []):
            if rec["sha256"] == actual_hash:
                print(f"  OK: {img_name} (attested {rec['timestamp']})")
                matched = True
                break
        if not matched:
            print(f"  UNATTESTED: {img_name} (hash: {actual_hash[:16]}...)")
            errors += 1

    # Verify chain linkage
    chain = manifest.get("chain_records", [])
    if chain:
        print(f"\\nVerifying chain linkage ({len(chain)} records)...")
        prev_hash = None
        for rec in chain:
            if prev_hash is not None and rec.get("prev_hash") != prev_hash:
                print(f"  BROKEN: record {rec['chain_index']} prev_hash mismatch")
                errors += 1
            # Simple hash for next check
            canonical = (
                rec["content_hash"] + rec["prev_hash"] +
                rec["signer_pubkey"] + str(rec["chain_index"]) +
                str(rec["claimed_ts"]) + rec["content_type"]
            )
            prev_hash = hashlib.sha256(canonical.encode()).hexdigest()
        print(f"  Chain: {len(chain)} records verified")

    print()
    if errors:
        print(f"FAILED: {errors} error(s)")
        sys.exit(1)
    else:
        print("PASSED: All evidence verified successfully.")
        sys.exit(0)

if __name__ == "__main__":
    main()
'''

    with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zf:
        zf.writestr("manifest.json", json.dumps(manifest, indent=2))
        zf.writestr("README.txt", readme)
        zf.writestr("verify.py", verify_script)
        if public_key_path and public_key_path.exists():
            zf.write(public_key_path, "public_key.pem")
        for img_path in image_paths:
            zf.write(img_path, f"images/{img_path.name}")

    return output_path
