"""
BloomOS Kernel - ChunkVault Handlers
====================================

Syscall handlers for chunk vault (CAS) operations.

Syscalls:
- chunkvault.get.v1: Get chunk from chunk vault by hash
- chunkvault.store.v1: Store data in chunk vault
- chunkvault.verify.v1: Verify chunk integrity
"""

from __future__ import annotations

import hashlib
from pathlib import Path
from typing import Any, Dict, TYPE_CHECKING

if TYPE_CHECKING:
    from ..syscall_registry import SyscallRegistry


# Default vault path
DEFAULT_VAULT_PATH = "/home/voidstr3m33/helix-cdc/vaults/default"


def chunkvault_get_v1(inputs: Dict[str, Any]) -> Dict[str, Any]:
    """
    Get chunk from chunk vault by hash.

    Wraps ChunkVaultHardened._load_chunk()

    Args (inputs dict):
        chunk_hash: SHA256 hash of chunk to retrieve
        vault_path: Optional vault path (default: /home/voidstr3m33/helix-cdc/vaults/default)
        verify: Whether to verify hash on read (default: True)

    Returns:
        {
            "status": "OK" | "FAIL",
            "chunk_data_b64": str (base64 encoded),
            "chunk_size": int,
            "chunk_hash": str,
            "verified": bool,
            "bytes_read": int,
        }
    """
    chunk_hash = inputs.get("chunk_hash")
    vault_path = inputs.get("vault_path", DEFAULT_VAULT_PATH)
    verify = inputs.get("verify", True)

    if not chunk_hash:
        return {
            "status": "FAIL",
            "error": "Missing required input: chunk_hash",
        }

    # Import vault
    try:
        from vaults.chunk_vault_hardened import ChunkVaultHardened
    except ImportError as e:
        return {
            "status": "FAIL",
            "error": f"Failed to import ChunkVaultHardened: {e}",
        }

    # Create vault instance
    vault = ChunkVaultHardened(vault_path)

    # Load chunk
    try:
        chunk_data = vault._load_chunk(chunk_hash, verify=verify)

        # Encode as base64 for JSON transport
        import base64
        chunk_data_b64 = base64.b64encode(chunk_data).decode("ascii")

        return {
            "status": "OK",
            "chunk_data_b64": chunk_data_b64,
            "chunk_size": len(chunk_data),
            "chunk_hash": chunk_hash,
            "verified": verify,
            "bytes_read": len(chunk_data),
        }

    except FileNotFoundError:
        return {
            "status": "FAIL",
            "error": f"Chunk not found: {chunk_hash}",
        }
    except ValueError as e:
        return {
            "status": "FAIL",
            "error": f"Chunk verification failed: {e}",
        }
    except Exception as e:
        return {
            "status": "FAIL",
            "error": str(e),
        }


def chunkvault_get_v1_cost_estimator(inputs: Dict[str, Any]) -> float:
    """
    Estimate IT cost for chunkvault.get.v1.

    Cost model:
    - Base cost: 0.01 IT
    - Per MB read: 0.001 IT (1 IT per GB)

    Args:
        inputs: Syscall inputs

    Returns:
        Estimated IT tokens
    """
    # Base cost is low since CAS reads are cheap
    return 0.01


def chunkvault_store_v1(inputs: Dict[str, Any]) -> Dict[str, Any]:
    """
    Store data in chunk vault.

    Wraps ChunkVaultHardened._store_chunk()

    Args (inputs dict):
        data_b64: Data to store (base64 encoded)
        vault_path: Optional vault path

    Returns:
        {
            "status": "OK" | "FAIL",
            "chunk_hash": str,
            "bytes_written": int,
            "deduplicated": bool,
        }
    """
    data_b64 = inputs.get("data_b64")
    vault_path = inputs.get("vault_path", DEFAULT_VAULT_PATH)

    if not data_b64:
        return {
            "status": "FAIL",
            "error": "Missing required input: data_b64",
        }

    # Import vault
    try:
        from vaults.chunk_vault_hardened import ChunkVaultHardened
    except ImportError as e:
        return {
            "status": "FAIL",
            "error": f"Failed to import ChunkVaultHardened: {e}",
        }

    # Decode base64
    import base64
    try:
        data = base64.b64decode(data_b64)
    except Exception as e:
        return {
            "status": "FAIL",
            "error": f"Invalid base64 data: {e}",
        }

    # Create vault instance
    vault = ChunkVaultHardened(vault_path)

    # Check if chunk already exists (deduplication)
    chunk_hash = hashlib.sha256(data).hexdigest()
    deduplicated = vault._chunk_exists(chunk_hash)

    # Store chunk
    try:
        stored_hash = vault._store_chunk(data)

        return {
            "status": "OK",
            "chunk_hash": stored_hash,
            "bytes_written": len(data) if not deduplicated else 0,
            "deduplicated": deduplicated,
        }

    except Exception as e:
        return {
            "status": "FAIL",
            "error": str(e),
        }


def chunkvault_store_v1_cost_estimator(inputs: Dict[str, Any]) -> float:
    """
    Estimate IT cost for chunkvault.store.v1.

    Cost model:
    - Base cost: 0.02 IT
    - Per MB written: 0.002 IT

    Args:
        inputs: Syscall inputs

    Returns:
        Estimated IT tokens
    """
    base_cost = 0.02
    per_mb_cost = 0.002

    data_b64 = inputs.get("data_b64", "")
    if not data_b64:
        return base_cost

    try:
        # Estimate decoded size (base64 is ~4/3 of original)
        decoded_size = len(data_b64) * 3 // 4
        mb = decoded_size / (1024 * 1024)
        return base_cost + (mb * per_mb_cost)
    except Exception:
        return base_cost


def chunkvault_verify_v1(inputs: Dict[str, Any]) -> Dict[str, Any]:
    """
    Verify chunk integrity.

    Args (inputs dict):
        chunk_hash: SHA256 hash to verify
        vault_path: Optional vault path

    Returns:
        {
            "status": "OK" | "FAIL",
            "exists": bool,
            "verified": bool,
            "actual_hash": str (if verification failed),
        }
    """
    chunk_hash = inputs.get("chunk_hash")
    vault_path = inputs.get("vault_path", DEFAULT_VAULT_PATH)

    if not chunk_hash:
        return {
            "status": "FAIL",
            "error": "Missing required input: chunk_hash",
        }

    # Import vault
    try:
        from vaults.chunk_vault_hardened import ChunkVaultHardened, sha256_bytes
    except ImportError as e:
        return {
            "status": "FAIL",
            "error": f"Failed to import ChunkVaultHardened: {e}",
        }

    vault = ChunkVaultHardened(vault_path)

    # Check existence
    if not vault._chunk_exists(chunk_hash):
        return {
            "status": "OK",
            "exists": False,
            "verified": False,
        }

    # Verify hash
    try:
        chunk_data = vault._load_chunk(chunk_hash, verify=False)
        actual_hash = sha256_bytes(chunk_data)

        if actual_hash == chunk_hash:
            return {
                "status": "OK",
                "exists": True,
                "verified": True,
            }
        else:
            return {
                "status": "OK",
                "exists": True,
                "verified": False,
                "actual_hash": actual_hash,
            }

    except Exception as e:
        return {
            "status": "FAIL",
            "error": str(e),
        }


def chunkvault_verify_v1_cost_estimator(inputs: Dict[str, Any]) -> float:
    """
    Estimate IT cost for chunkvault.verify.v1.

    Cost model:
    - Fixed cost: 0.01 IT (verification is cheap)

    Args:
        inputs: Syscall inputs

    Returns:
        Estimated IT tokens
    """
    return 0.01


# Schema definitions
CHUNKVAULT_GET_V1_SCHEMA = {
    "required": ["chunk_hash"],
    "types": {
        "chunk_hash": "str",
        "vault_path": "str",
        "verify": "bool",
    },
}

CHUNKVAULT_STORE_V1_SCHEMA = {
    "required": ["data_b64"],
    "types": {
        "data_b64": "str",
        "vault_path": "str",
    },
}

CHUNKVAULT_VERIFY_V1_SCHEMA = {
    "required": ["chunk_hash"],
    "types": {
        "chunk_hash": "str",
        "vault_path": "str",
    },
}


def register_chunkvault_handlers(registry: "SyscallRegistry") -> None:
    """Register chunkvault handlers with the registry."""
    registry.register(
        canonical_name="chunkvault.get.v1",
        handler=chunkvault_get_v1,
        schema=CHUNKVAULT_GET_V1_SCHEMA,
        cost_estimator=chunkvault_get_v1_cost_estimator,
        description="Get chunk from chunk vault by hash (wraps ChunkVaultHardened)",
    )

    registry.register(
        canonical_name="chunkvault.store.v1",
        handler=chunkvault_store_v1,
        schema=CHUNKVAULT_STORE_V1_SCHEMA,
        cost_estimator=chunkvault_store_v1_cost_estimator,
        description="Store data in chunk vault (atomic write with deduplication)",
    )

    registry.register(
        canonical_name="chunkvault.verify.v1",
        handler=chunkvault_verify_v1,
        schema=CHUNKVAULT_VERIFY_V1_SCHEMA,
        cost_estimator=chunkvault_verify_v1_cost_estimator,
        description="Verify chunk integrity in vault",
    )
