#!/usr/bin/env python3
"""
fibpi3d_timing.py - Golden Ratio (Φ) Timing and Resonance
==========================================================

FibPi3D timing uses the golden ratio (Φ ≈ 1.618) for:
- Staggered request scheduling (anti-beat interference)
- Resonance measurement (Fibonacci alignment)
- Phase synchronization

Consolidated from:
- receipts/.../runtime/reflexes/fibpi3d_pulse_reflex__v3.py
- fibpi3d_petal_forge concepts

WO#NET_JAZZ_00

NOTE: This module tries to use C bindings (libhelix_cdc.so) first for
60,000x speedup. Falls back to Python if C library not available.
"""

from __future__ import annotations
import math
import time
from dataclasses import dataclass
from datetime import datetime
from typing import List, Dict, Any, Optional

# Golden ratio (Φ)
GOLDEN_RATIO = (1 + math.sqrt(5)) / 2  # ≈ 1.618033988749895

# Fibonacci sequence (first 12)
FIBONACCI = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]

# ============================================================================
# TRY C BINDINGS FIRST (60,000x faster)
# ============================================================================

_C_LIB = None
_USE_C = False

try:
    from helix_cdc.c_bindings import get_lib
    _C_LIB = get_lib()
    if _C_LIB.available:
        _USE_C = True
except ImportError:
    pass


def using_c_bindings() -> bool:
    """Check if C bindings are being used (60,000x faster)."""
    return _USE_C


def get_backend_info() -> Dict[str, Any]:
    """Get info about which backend is being used."""
    return {
        "using_c": _USE_C,
        "backend": "C (libhelix_cdc.so)" if _USE_C else "Python (fallback)",
        "speedup": "~60,000x" if _USE_C else "1x (baseline)",
    }


def phi_delay(base_delay: float, index: int) -> float:
    """
    Calculate Φ-staggered delay for request index.

    The delay grows by Φ for each successive request,
    providing natural spacing that avoids beat patterns.

    Args:
        base_delay: Base delay in seconds
        index: Request index (0-based)

    Returns:
        Delay in seconds for this request
    """
    if _USE_C:
        return _C_LIB.phi_delay(base_delay, index)
    return base_delay * (GOLDEN_RATIO ** index)


def phi_stagger_delays(
    count: int,
    base_delay: float = 0.1,
    max_delay: Optional[float] = None,
) -> List[float]:
    """
    Generate Φ-staggered delay sequence.

    Args:
        count: Number of delays to generate
        base_delay: Base delay in seconds
        max_delay: Optional maximum delay cap

    Returns:
        List of delays in seconds
    """
    if _USE_C and max_delay is not None:
        # Use C library for batch generation
        return list(_C_LIB.phi_stagger_delays(count, base_delay, max_delay))

    # Python fallback
    delays = []
    for i in range(count):
        delay = phi_delay(base_delay, i)
        if max_delay is not None:
            delay = min(delay, max_delay)
        delays.append(delay)
    return delays


def fibonacci_at(n: int) -> int:
    """
    Get Fibonacci number at index n.

    Args:
        n: Index (0-based)

    Returns:
        Fibonacci number
    """
    if _USE_C:
        return _C_LIB.fibonacci_at(n)

    # Python fallback
    if n < len(FIBONACCI):
        return FIBONACCI[n]

    # Compute dynamically
    a, b = FIBONACCI[-2], FIBONACCI[-1]
    for _ in range(len(FIBONACCI), n + 1):
        a, b = b, a + b
    return b


def measure_resonance(values: List[float]) -> float:
    """
    Measure how well values align with Fibonacci/Φ spacing.

    Returns a score 0-1 where 1 = perfect Fibonacci alignment.

    Args:
        values: List of numeric values (e.g., port numbers, delays)

    Returns:
        Resonance score (0-1)
    """
    if len(values) < 2:
        return 1.0

    # Calculate consecutive ratios
    ratios = []
    for i in range(1, len(values)):
        if values[i-1] != 0:
            ratios.append(values[i] / values[i-1])

    if not ratios:
        return 0.0

    # Measure deviation from Φ
    deviations = [abs(r - GOLDEN_RATIO) for r in ratios]
    avg_deviation = sum(deviations) / len(deviations)

    # Convert to 0-1 score (lower deviation = higher score)
    # Deviation of 0 = score 1, deviation of Φ = score 0
    score = max(0.0, 1.0 - (avg_deviation / GOLDEN_RATIO))

    return score


def check_phi_alignment(
    values: List[float],
    threshold: float = 0.7,
) -> Dict[str, Any]:
    """
    Check if values are Φ-aligned and report alignment status.

    Args:
        values: List of values to check
        threshold: Minimum resonance score for alignment

    Returns:
        Dict with alignment analysis
    """
    resonance = measure_resonance(values)
    aligned = resonance >= threshold

    return {
        "values": values,
        "resonance_score": resonance,
        "threshold": threshold,
        "aligned": aligned,
        "status": "ALIGNED" if aligned else "DRIFT",
        "golden_ratio": GOLDEN_RATIO,
        "timestamp": datetime.now().isoformat(),
    }


@dataclass
class PhiScheduler:
    """Φ-staggered request scheduler."""
    base_delay: float = 0.1
    max_delay: float = 5.0
    index: int = 0

    def next_delay(self) -> float:
        """Get next Φ-staggered delay."""
        delay = min(phi_delay(self.base_delay, self.index), self.max_delay)
        self.index += 1
        return delay

    def reset(self) -> None:
        """Reset scheduler index."""
        self.index = 0

    def schedule_batch(
        self,
        count: int,
        action: callable,
    ) -> List[Dict[str, Any]]:
        """
        Execute batch of actions with Φ-staggered timing.

        Args:
            count: Number of actions
            action: Callable to execute

        Returns:
            List of action results with timing
        """
        results = []
        self.reset()

        for i in range(count):
            if i > 0:
                delay = self.next_delay()
                time.sleep(delay)
            else:
                delay = 0.0

            start = time.time()
            try:
                result = action()
                elapsed = time.time() - start
                results.append({
                    "index": i,
                    "delay": delay,
                    "elapsed": elapsed,
                    "result": result,
                    "status": "ok",
                })
            except Exception as e:
                elapsed = time.time() - start
                results.append({
                    "index": i,
                    "delay": delay,
                    "elapsed": elapsed,
                    "error": str(e),
                    "status": "error",
                })

        return results


# ============================================================================
# CLI
# ============================================================================

def _cli():
    """FibPi3D Timing CLI."""
    import argparse
    import json

    parser = argparse.ArgumentParser(description="FibPi3D Timing Analysis")
    parser.add_argument("--delays", type=int, default=10,
                        help="Number of Φ-staggered delays to generate")
    parser.add_argument("--base", type=float, default=0.1,
                        help="Base delay in seconds")
    parser.add_argument("--check", type=str,
                        help="Comma-separated values to check alignment")
    parser.add_argument("--json", action="store_true",
                        help="Output JSON")
    args = parser.parse_args()

    if args.check:
        values = [float(v) for v in args.check.split(",")]
        result = check_phi_alignment(values)
        if args.json:
            print(json.dumps(result, indent=2))
        else:
            print(f"Resonance: {result['resonance_score']:.3f}")
            print(f"Status: {result['status']}")
    else:
        delays = phi_stagger_delays(args.delays, base_delay=args.base)
        print(f"Φ-Staggered Delays (base={args.base}s):")
        print(f"  Golden Ratio (Φ): {GOLDEN_RATIO:.6f}")
        print()
        for i, d in enumerate(delays):
            print(f"  {i}: {d:.4f}s")
        print()
        print(f"Total: {sum(delays):.4f}s for {len(delays)} requests")


if __name__ == "__main__":
    _cli()
