#!/usr/bin/env python3
"""
PCILeech Build Integration Module
Generated by PCILeech Firmware Generator

Clean, focused build integration without template bloat.
"""

import logging
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional

logger = logging.getLogger(__name__)


@dataclass
class TimingConfig:
    """Timing configuration parameters."""
    clock_frequency_mhz: float = 100.0
    read_latency: int = 4
    write_latency: int = 2
    burst_length: int = 16
    timeout_cycles: int = 1024


@dataclass
class DeviceConfig:
    """Device configuration parameters."""
    device_bdf: str
    vendor_id: str
    device_id: str
    enable_advanced_features: bool = False
    enable_dma_operations: bool = False
    enable_perf_counters: bool = False


@dataclass
class PCILeechConfig:
    """PCILeech-specific configuration."""
    command_timeout: int = 1000
    buffer_size: int = 4096
    enable_scatter_gather: bool = True
    max_payload_size: int = 256
    max_read_request_size: int = 512


@dataclass
class BuildConfig:
    """Complete build configuration."""
    device: DeviceConfig
    timing: TimingConfig
    pcileech: PCILeechConfig
    pcileech_modules: List[str] = field(default_factory=lambda: {{ pcileech_modules | python_list }})
    build_system_version: str = "{{ build_system_version }}"
    integration_type: str = "{{ integration_type }}"


class PCILeechBuildIntegrator:
    """Clean, focused PCILeech build integrator."""
    
    def __init__(self, config: BuildConfig):
        self.config = config
    
    def get_systemverilog_files(self) -> List[str]:
        """Get SystemVerilog files for the build."""
        files = [f"src/{module}.sv" for module in self.config.pcileech_modules]
        
        if self.config.device.enable_advanced_features:
            files.extend([
                "src/pcileech_advanced_controller.sv",
                "src/advanced_error_handling.sv",
                "src/performance_counters.sv",
            ])
        
        if self.config.device.enable_dma_operations:
            files.extend([
                "src/dma_controller.sv",
                "src/scatter_gather_engine.sv",
            ])
        
        return files
    
    def get_constraint_files(self) -> List[str]:
        """Get constraint files for the build."""
        files = ["constraints/pcileech_timing.xdc"]
        
        if self.config.timing.clock_frequency_mhz > 150.0:
            files.append("constraints/high_frequency.xdc")
        elif self.config.timing.clock_frequency_mhz < 50.0:
            files.append("constraints/low_frequency.xdc")
        
        if self.config.device.enable_advanced_features:
            files.append("constraints/advanced_features.xdc")
        
        return files
    
    def get_build_parameters(self) -> Dict[str, Any]:
        """Get build parameters for TCL generation."""
        return {
            "device_bdf": self.config.device.device_bdf,
            "vendor_id": self.config.device.vendor_id,
            "device_id": self.config.device.device_id,
            "clock_frequency_mhz": self.config.timing.clock_frequency_mhz,
            "read_latency_cycles": self.config.timing.read_latency,
            "write_latency_cycles": self.config.timing.write_latency,
            "pcileech_buffer_size": self.config.pcileech.buffer_size,
            "pcileech_command_timeout": self.config.pcileech.command_timeout,
            "enable_advanced_features": self.config.device.enable_advanced_features,
            "enable_dma_operations": self.config.device.enable_dma_operations,
        }
    
    def validate(self) -> List[str]:
        """Validate configuration and return any errors."""
        errors = []
        
        if not self.config.device.device_bdf:
            errors.append("Device BDF is required")
        
        if not self.config.device.vendor_id:
            errors.append("Vendor ID is required")
        
        if not self.config.device.device_id:
            errors.append("Device ID is required")
        
        if self.config.timing.clock_frequency_mhz <= 0 or self.config.timing.clock_frequency_mhz > 500:
            errors.append(f"Invalid clock frequency: {self.config.timing.clock_frequency_mhz} MHz")
        
        if self.config.pcileech.buffer_size < 1024 or self.config.pcileech.buffer_size > 65536:
            errors.append(f"Invalid buffer size: {self.config.pcileech.buffer_size} bytes")
        
        if not self.config.pcileech_modules:
            errors.append("No PCILeech modules specified")
        
        return errors


def create_build_config(build_data: Dict[str, Any]) -> BuildConfig:
    """Create BuildConfig from legacy dict format."""
    device_data = build_data.get("device_config", {})
    timing_data = build_data.get("timing_config", {})
    pcileech_data = build_data.get("pcileech_config", {})
    
    device = DeviceConfig(
        device_bdf=device_data.get("device_bdf", ""),
        vendor_id=device_data.get("vendor_id", ""),
        device_id=device_data.get("device_id", ""),
        enable_advanced_features=device_data.get("enable_advanced_features", False),
        enable_dma_operations=device_data.get("enable_dma_operations", False),
        enable_perf_counters=device_data.get("enable_perf_counters", False),
    )
    
    timing = TimingConfig(
        clock_frequency_mhz=timing_data.get("clock_frequency_mhz", 100.0),
        read_latency=timing_data.get("read_latency", 4),
        write_latency=timing_data.get("write_latency", 2),
        burst_length=timing_data.get("burst_length", 16),
        timeout_cycles=timing_data.get("timeout_cycles", 1024),
    )
    
    pcileech = PCILeechConfig(
        command_timeout=pcileech_data.get("command_timeout", 1000),
        buffer_size=pcileech_data.get("buffer_size", 4096),
        enable_scatter_gather=pcileech_data.get("enable_scatter_gather", True),
        max_payload_size=pcileech_data.get("max_payload_size", 256),
        max_read_request_size=pcileech_data.get("max_read_request_size", 512),
    )
    
    return BuildConfig(
        device=device,
        timing=timing,
        pcileech=pcileech,
        pcileech_modules=build_data.get("pcileech_modules", []),
        build_system_version=build_data.get("build_system_version", "0.7.3"),
        integration_type=build_data.get("integration_type", "pcileech"),
    )


def integrate_pcileech_build(build_data: Dict[str, Any]) -> Dict[str, Any]:
    """Main integration function for PCILeech build system."""
    config = create_build_config(build_data)
    integrator = PCILeechBuildIntegrator(config)
    
    # Validate configuration
    validation_errors = integrator.validate()
    if validation_errors:
        raise ValueError(f"Build configuration validation failed: {validation_errors}")
    
    # Generate build artifacts
    return {
        "build_parameters": integrator.get_build_parameters(),
        "systemverilog_files": integrator.get_systemverilog_files(),
        "constraint_files": integrator.get_constraint_files(),
        "integration_metadata": {
            "build_system_version": config.build_system_version,
            "integration_type": config.integration_type,
        }
    }


if __name__ == "__main__":
    # Example usage
    example_data = {
        "device_config": {
            "device_bdf": "0000:03:00.0",
            "vendor_id": "8086",
            "device_id": "15B8",
            "enable_advanced_features": True,
            "enable_dma_operations": True,
        },
        "timing_config": {
            "clock_frequency_mhz": 125.0,
            "read_latency": 4,
            "write_latency": 2,
        },
        "pcileech_config": {
            "buffer_size": 4096,
            "command_timeout": 1000,
        },
        "pcileech_modules": ["pcileech_fifo", "bar_controller"],
    }
    
    try:
        results = integrate_pcileech_build(example_data)
        print("PCILeech build integration successful")
        print(f"Generated {len(results['systemverilog_files'])} SystemVerilog files")
    except Exception as e:
        print(f"PCILeech build integration failed: {e}")