#!/usr/bin/env python3
"""
Sign assets in the registry with giles's private key.

Creates ActivityPub Create activities with RSA signatures.
"""

import base64
import hashlib
import json
import sys
import uuid
from datetime import datetime, timezone
from pathlib import Path

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.backends import default_backend


def load_private_key(path: Path):
    """Load private key from PEM file."""
    pem_data = path.read_bytes()
    return serialization.load_pem_private_key(pem_data, password=None, backend=default_backend())


def sign_data(private_key, data: str) -> str:
    """Sign data with RSA private key, return base64 signature."""
    signature = private_key.sign(
        data.encode(),
        padding.PKCS1v15(),
        hashes.SHA256(),
    )
    return base64.b64encode(signature).decode()


def create_activity(actor_id: str, asset_name: str, cid: str, asset_type: str, domain: str = "artdag.rose-ash.com"):
    """Create a Create activity for an asset."""
    now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")

    return {
        "activity_id": str(uuid.uuid4()),
        "activity_type": "Create",
        "actor_id": actor_id,
        "object_data": {
            "type": asset_type_to_ap(asset_type),
            "name": asset_name,
            "id": f"https://{domain}/objects/{cid}",
            "contentHash": {
                "algorithm": "sha3-256",
                "value": cid
            },
            "attributedTo": actor_id
        },
        "published": now,
    }


def asset_type_to_ap(asset_type: str) -> str:
    """Convert asset type to ActivityPub type."""
    type_map = {
        "image": "Image",
        "video": "Video",
        "audio": "Audio",
        "effect": "Application",
        "infrastructure": "Application",
    }
    return type_map.get(asset_type, "Document")


def sign_activity(activity: dict, private_key, actor_id: str, domain: str = "artdag.rose-ash.com") -> dict:
    """Add signature to activity."""
    # Create canonical string to sign
    to_sign = json.dumps(activity["object_data"], sort_keys=True, separators=(",", ":"))

    signature_value = sign_data(private_key, to_sign)

    activity["signature"] = {
        "type": "RsaSignature2017",
        "creator": f"{actor_id}#main-key",
        "created": activity["published"],
        "signatureValue": signature_value
    }

    return activity


def main():
    username = "giles"
    domain = "artdag.rose-ash.com"
    actor_id = f"https://{domain}/users/{username}"

    # Load private key
    private_key_path = Path.home() / ".artdag" / "keys" / f"{username}.pem"
    if not private_key_path.exists():
        print(f"Private key not found: {private_key_path}")
        print("Run setup_actor.py first.")
        sys.exit(1)

    private_key = load_private_key(private_key_path)
    print(f"Loaded private key: {private_key_path}")

    # Load registry
    registry_path = Path.home() / "artdag-registry" / "registry.json"
    with open(registry_path) as f:
        registry = json.load(f)

    # Create signed activities for each asset
    activities = []

    for asset_name, asset_data in registry["assets"].items():
        print(f"\nSigning: {asset_name}")
        print(f"  Hash: {asset_data['cid'][:16]}...")

        activity = create_activity(
            actor_id=actor_id,
            asset_name=asset_name,
            cid=asset_data["cid"],
            asset_type=asset_data["asset_type"],
            domain=domain,
        )

        signed_activity = sign_activity(activity, private_key, actor_id, domain)
        activities.append(signed_activity)

        print(f"  Activity ID: {signed_activity['activity_id']}")
        print(f"  Signature: {signed_activity['signature']['signatureValue'][:32]}...")

    # Save activities
    activities_path = Path.home() / "artdag-registry" / "activities.json"
    activities_data = {
        "version": "1.0",
        "activities": activities
    }

    with open(activities_path, "w") as f:
        json.dump(activities_data, f, indent=2)

    print(f"\nSaved {len(activities)} signed activities to: {activities_path}")


if __name__ == "__main__":
    main()
