package dsp

import (
	"math"
	"testing"
)

func TestPreEmphasisBoostsHighFrequency(t *testing.T) {
	fs := 48000.0
	pe := NewPreEmphasis(50, fs)

	// Generate a low-frequency tone and a high-frequency tone,
	// measure the energy ratio after pre-emphasis.
	n := 4800 // 100ms
	lowFreq := 100.0
	highFreq := 10000.0

	var lowEnergy, highEnergy float64
	for i := 0; i < n; i++ {
		s := math.Sin(2 * math.Pi * lowFreq * float64(i) / fs)
		out := pe.Process(s)
		lowEnergy += out * out
	}
	pe.Reset()
	for i := 0; i < n; i++ {
		s := math.Sin(2 * math.Pi * highFreq * float64(i) / fs)
		out := pe.Process(s)
		highEnergy += out * out
	}

	// High frequency should have more energy than low frequency
	// after pre-emphasis. The input energy is the same for both.
	ratio := highEnergy / lowEnergy
	if ratio < 2.0 {
		t.Fatalf("expected high-freq boost, energy ratio=%.2f", ratio)
	}
}

func TestPreEmphasisDeEmphasisRoundtrip(t *testing.T) {
	fs := 48000.0
	pe := NewPreEmphasis(50, fs)
	de := NewDeEmphasis(50, fs)

	// Run a 1kHz tone through pre+de, should approximately recover
	n := 4800
	freq := 1000.0
	var maxErr float64

	// Let filters settle for 200 samples
	for i := 0; i < 200; i++ {
		s := math.Sin(2 * math.Pi * freq * float64(i) / fs)
		de.Process(pe.Process(s))
	}
	for i := 200; i < n; i++ {
		s := math.Sin(2 * math.Pi * freq * float64(i) / fs)
		recovered := de.Process(pe.Process(s))
		err := math.Abs(recovered - s)
		if err > maxErr {
			maxErr = err
		}
	}
	if maxErr > 0.05 {
		t.Fatalf("roundtrip error too large: %.4f", maxErr)
	}
}

func TestDisabledPreEmphasis(t *testing.T) {
	pe := NewPreEmphasis(0, 48000)
	if pe.Process(0.5) != 0.5 {
		t.Fatal("disabled filter should pass through")
	}
}
