"""
Demo ID Transformer Utility

Provides XOR-based ID transformation for creating unique but deterministic
IDs across different demo tenants while maintaining cross-service consistency.

This ensures that:
1. Same base ID + same tenant ID = same transformed ID (deterministic)
2. Different tenant IDs = different transformed IDs (isolation)
3. Cross-service relationships are preserved (consistency)
"""

import uuid
from typing import Union


def transform_id(base_id: Union[str, uuid.UUID], tenant_id: Union[str, uuid.UUID]) -> uuid.UUID:
    """
    Transform a base ID using XOR with tenant ID to create unique but deterministic IDs.
    
    Args:
        base_id: Original UUID (string or UUID object)
        tenant_id: Tenant UUID (string or UUID object)
        
    Returns:
        Transformed UUID that is unique to this tenant but deterministic
        
    Example:
        >>> base_uuid = UUID('10000000-0000-0000-0000-000000000001')
        >>> tenant_uuid = UUID('a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6')
        >>> transform_id(base_uuid, tenant_uuid)
        # Returns deterministic UUID based on XOR of the two
    """
    # Convert inputs to UUID objects if they aren't already
    if isinstance(base_id, str):
        base_uuid = uuid.UUID(base_id)
    else:
        base_uuid = base_id
        
    if isinstance(tenant_id, str):
        tenant_uuid = uuid.UUID(tenant_id)
    else:
        tenant_uuid = tenant_id
    
    # Convert UUIDs to 16-byte arrays
    base_bytes = base_uuid.bytes
    tenant_bytes = tenant_uuid.bytes
    
    # Apply XOR transformation
    transformed_bytes = bytes(b1 ^ b2 for b1, b2 in zip(base_bytes, tenant_bytes))
    
    # Create new UUID from transformed bytes
    transformed_uuid = uuid.UUID(bytes=transformed_bytes)
    
    return transformed_uuid


def generate_deterministic_uuid_from_string(input_string: str, tenant_id: Union[str, uuid.UUID]) -> uuid.UUID:
    """
    Generate a deterministic UUID from a string input and tenant ID.
    
    Useful for transforming non-UUID identifiers (like SKUs) into UUIDs
    while maintaining determinism across services.
    
    Args:
        input_string: String identifier (e.g., SKU, product code)
        tenant_id: Tenant UUID for isolation
        
    Returns:
        Deterministic UUID based on the input string and tenant
    """
    if isinstance(tenant_id, str):
        tenant_uuid = uuid.UUID(tenant_id)
    else:
        tenant_uuid = tenant_id
    
    # Create a combined string for hashing
    combined = f"{input_string}-{tenant_uuid}"
    
    # Use SHA-256 hash to create deterministic UUID
    import hashlib
    hash_obj = hashlib.sha256(combined.encode('utf-8'))
    
    # Use first 16 bytes for UUID v5 namespace
    hash_bytes = hash_obj.digest()[:16]
    
    # Create UUID v5 using a standard namespace
    namespace_uuid = uuid.NAMESPACE_DNS  # Using DNS namespace as base
    deterministic_uuid = uuid.uuid5(namespace_uuid, combined)
    
    return deterministic_uuid


# Utility functions for common transformations

def transform_ingredient_id(base_ingredient_id: Union[str, uuid.UUID], tenant_id: Union[str, uuid.UUID]) -> uuid.UUID:
    """Transform an ingredient ID for a specific tenant"""
    return transform_id(base_ingredient_id, tenant_id)


def transform_recipe_id(base_recipe_id: Union[str, uuid.UUID], tenant_id: Union[str, uuid.UUID]) -> uuid.UUID:
    """Transform a recipe ID for a specific tenant"""
    return transform_id(base_recipe_id, tenant_id)


def transform_supplier_id(base_supplier_id: Union[str, uuid.UUID], tenant_id: Union[str, uuid.UUID]) -> uuid.UUID:
    """Transform a supplier ID for a specific tenant"""
    return transform_id(base_supplier_id, tenant_id)


def transform_production_batch_id(base_batch_id: Union[str, uuid.UUID], tenant_id: Union[str, uuid.UUID]) -> uuid.UUID:
    """Transform a production batch ID for a specific tenant"""
    return transform_id(base_batch_id, tenant_id)