#!/usr/bin/env python3
"""Test the C++ NAM engine integrated into the pipeline."""
import sys, types, time
import numpy as np

# Mock tkinter to allow nam package import
tk = types.ModuleType('tkinter')
tk.Tk = type('MockTk', (), {'__init__': lambda s: None})
sys.modules['tkinter'] = tk

sys.path.insert(0, 'src')
from dsp.pipeline import AudioPipeline
from presets.types import Preset, FXBlock, FXType

# Create pipeline
p = AudioPipeline()
print(f"NAM type: {type(p.nam).__name__}")

# Load a NAM model
ok = p.nam.load_model('models/nam/clean.nam')
print(f"Model loaded: {ok}, is_loaded={p.nam.is_loaded}")
if p.nam._engine:
    print(f"  Static: {p.nam._engine.is_static}, SampleRate: {p.nam._engine._sample_rate}")

# Test NAM engine directly
block = np.sin(2 * np.pi * 440 * np.arange(256) / 48000).astype(np.float32) * 0.3
processed = p.nam.process(block)
print(f"NAM direct: in_rms={np.sqrt(np.mean(block**2)):.4f} out_rms={np.sqrt(np.mean(processed**2)):.4f}")

# Test through pipeline
preset = Preset(name='test', bank=0, program=0, chain=[
    FXBlock(fx_type=FXType.NOISE_GATE, enabled=True, params={'threshold': 0.01}),
    FXBlock(fx_type=FXType.NAM_AMP, enabled=True, params={'level': 0.8, 'gain': 0.5},
            nam_model_path='models/nam/clean.nam'),
])
p.load_preset(preset)
print(f"Preset loaded: {len(p._chain)} blocks")

out = p.process(block)
print(f"Pipeline out: in_rms={np.sqrt(np.mean(block**2)):.4f} out_rms={np.sqrt(np.mean(out**2)):.4f}")

# Benchmark
times = []
for _ in range(500):
    t0 = time.perf_counter()
    p.process(block)
    times.append((time.perf_counter() - t0) * 1000)
print(f"Pipeline avg: {np.mean(times):.3f} ms, max: {np.max(times):.3f} ms, min: {np.min(times):.3f} ms")
print(f"VU meter: input={p._input_level:.4f} output={p._output_level:.4f}")

p.nam.unload()
print("SUCCESS")
