import XCTest
@testable import SherpaOnnxOfflineStt

/// Unit tests for STTConstants configuration values
class STTConstantsTests: XCTestCase {

    // MARK: - Audio Processing Tests

    func testAudioProcessingConstants() {
        XCTAssertEqual(STTConstants.defaultSampleRate, 16000)
        XCTAssertEqual(STTConstants.vadHopSize, 160)
        XCTAssertEqual(STTConstants.maxDenoiserChunkSamples, 5 * 16000)
        XCTAssertEqual(STTConstants.audioChunkSizeMs, 80)
    }

    func testMinPeakForSTT() {
        XCTAssertGreaterThan(STTConstants.minPeakForSTT, 0)
        XCTAssertLessThan(STTConstants.minPeakForSTT, 1)
    }

    func testTargetPeakAmplitude() {
        XCTAssertGreaterThan(STTConstants.targetPeakAmplitude, 0)
        XCTAssertLessThanOrEqual(STTConstants.targetPeakAmplitude, 1)
    }

    // MARK: - VAD Constants Tests

    func testVADThresholdRange() {
        XCTAssertGreaterThanOrEqual(STTConstants.defaultVadThreshold, 0)
        XCTAssertLessThanOrEqual(STTConstants.defaultVadThreshold, 1)
        XCTAssertGreaterThanOrEqual(STTConstants.vadThresholdMin, 0)
        XCTAssertLessThanOrEqual(STTConstants.vadThresholdMax, 1)
        XCTAssertLessThan(STTConstants.vadThresholdMin, STTConstants.vadThresholdMax)
    }

    func testVADTimingConstants() {
        XCTAssertGreaterThan(STTConstants.defaultMinSpeechMs, 0)
        XCTAssertGreaterThan(STTConstants.defaultMinSilenceMs, 0)
        XCTAssertGreaterThan(STTConstants.defaultMaxSpeechMs, 0)
        XCTAssertGreaterThanOrEqual(STTConstants.defaultSpeechPaddingMs, 0)
    }

    func testVADModeAdjustments() {
        // Aggressive mode increases threshold (less sensitive)
        XCTAssertGreaterThan(STTConstants.vadModeAggressiveAdjustment, 0)
        // Sensitive mode decreases threshold (more sensitive)
        XCTAssertLessThan(STTConstants.vadModeSensitiveAdjustment, 0)
    }

    // MARK: - Diarization Constants Tests

    func testDiarizationThresholdRange() {
        XCTAssertGreaterThanOrEqual(STTConstants.defaultSpeakerThreshold, 0)
        XCTAssertLessThanOrEqual(STTConstants.defaultSpeakerThreshold, 1)
        XCTAssertGreaterThanOrEqual(STTConstants.defaultEmbeddingThreshold, 0)
        XCTAssertLessThanOrEqual(STTConstants.defaultEmbeddingThreshold, 1)
    }

    func testSpeakerThresholdIsMoreLenient() {
        // Speaker matching should use a lower threshold than profile updates
        XCTAssertLessThan(STTConstants.defaultSpeakerThreshold, STTConstants.defaultEmbeddingThreshold)
    }

    func testDiarizationTimingConstants() {
        XCTAssertGreaterThan(STTConstants.defaultMinSpeechDurationMs, 0)
        XCTAssertGreaterThan(STTConstants.defaultMinEmbeddingUpdateMs, 0)
        XCTAssertGreaterThan(STTConstants.defaultMaxSpeakers, 0)
    }

    func testDiarizationWindowConstants() {
        XCTAssertGreaterThan(STTConstants.diarizationWindowSizeMs, 0)
        XCTAssertGreaterThan(STTConstants.diarizationWindowStepMs, 0)
        // Step should be <= size for proper overlap
        XCTAssertLessThanOrEqual(STTConstants.diarizationWindowStepMs, STTConstants.diarizationWindowSizeMs)
    }

    func testMinSpeechForNewSpeaker() {
        // New speaker creation requires more accumulated speech than min duration
        XCTAssertGreaterThanOrEqual(STTConstants.defaultMinSpeechForNewSpeaker, STTConstants.defaultMinSpeechDurationMs)
    }

    // MARK: - Streaming State Tests

    func testStreamingStateConstants() {
        XCTAssertGreaterThanOrEqual(STTConstants.defaultConfirmationThreshold, 0)
        XCTAssertLessThanOrEqual(STTConstants.defaultConfirmationThreshold, 1)
        XCTAssertGreaterThan(STTConstants.defaultMinContextMs, 0)
    }

    // MARK: - Embedding Validation Tests

    func testEmbeddingValidationConstants() {
        XCTAssertGreaterThan(STTConstants.minEmbeddingNorm, 0)
        XCTAssertGreaterThan(STTConstants.embeddingQualityFactor, 0)
    }

    // MARK: - Pyannote Constants Tests

    func testPyannoteDefaults() {
        XCTAssertGreaterThanOrEqual(STTConstants.defaultClusteringThreshold, 0)
        XCTAssertLessThanOrEqual(STTConstants.defaultClusteringThreshold, 1)
        XCTAssertGreaterThan(STTConstants.defaultMinDurationOn, 0)
        XCTAssertGreaterThan(STTConstants.defaultMinDurationOff, 0)
    }

    // MARK: - Model Inference Tests

    func testModelInferenceConstants() {
        XCTAssertGreaterThan(STTConstants.defaultSTTNumThreads, 0)
        XCTAssertGreaterThan(STTConstants.defaultAuxiliaryNumThreads, 0)
        XCTAssertFalse(STTConstants.defaultProvider.isEmpty)
    }
}
