import XCTest
@testable import MixBoard

final class CodecTests: XCTestCase {

    // MARK: - OGGDecoder Error Descriptions

    func testOGGFailedToOpenErrorDescription() {
        let error = OGGDecoder.OGGError.failedToOpen("test.ogg")
        XCTAssertEqual(error.errorDescription, "Failed to open OGG file: test.ogg")
    }

    func testOGGFailedToCreateBufferErrorDescription() {
        let error = OGGDecoder.OGGError.failedToCreateBuffer
        XCTAssertEqual(error.errorDescription, "Failed to create audio buffer")
    }

    func testOGGDecodingFailedErrorDescription() {
        let error = OGGDecoder.OGGError.decodingFailed
        XCTAssertEqual(error.errorDescription, "OGG decoding failed")
    }

    // MARK: - OpusDecoder Error Descriptions

    #if !DISABLE_OPUS
    func testOpusFailedToOpenErrorDescription() {
        let error = OpusDecoder.OpusError.failedToOpen("test.opus", -1)
        XCTAssertTrue(error.errorDescription!.contains("test.opus"))
        XCTAssertTrue(error.errorDescription!.contains("-1"))
    }

    func testOpusFailedToCreateBufferErrorDescription() {
        let error = OpusDecoder.OpusError.failedToCreateBuffer
        XCTAssertEqual(error.errorDescription, "Failed to create audio buffer")
    }

    func testOpusDecodingFailedErrorDescription() {
        let error = OpusDecoder.OpusError.decodingFailed
        XCTAssertEqual(error.errorDescription, "Opus decoding failed")
    }
    #endif

    // MARK: - isOGGFile

    func testIsOGGFileTrue() {
        XCTAssertTrue(OGGDecoder.isOGGFile(URL(fileURLWithPath: "/path/to/file.ogg")))
    }

    func testIsOGGFileFalse() {
        XCTAssertFalse(OGGDecoder.isOGGFile(URL(fileURLWithPath: "/path/to/file.mp3")))
        XCTAssertFalse(OGGDecoder.isOGGFile(URL(fileURLWithPath: "/path/to/file.flac")))
        XCTAssertFalse(OGGDecoder.isOGGFile(URL(fileURLWithPath: "/path/to/file.opus")))
    }

    func testIsOGGFileCaseInsensitive() {
        XCTAssertTrue(OGGDecoder.isOGGFile(URL(fileURLWithPath: "/path/to/file.OGG")))
    }

    // MARK: - isOpusFile

    #if !DISABLE_OPUS
    func testIsOpusFileTrue() {
        XCTAssertTrue(OpusDecoder.isOpusFile(URL(fileURLWithPath: "/path/to/file.opus")))
    }

    func testIsOpusFileFalse() {
        XCTAssertFalse(OpusDecoder.isOpusFile(URL(fileURLWithPath: "/path/to/file.ogg")))
        XCTAssertFalse(OpusDecoder.isOpusFile(URL(fileURLWithPath: "/path/to/file.mp3")))
        XCTAssertFalse(OpusDecoder.isOpusFile(URL(fileURLWithPath: "/path/to/file.wav")))
    }

    func testIsOpusFileCaseInsensitive() {
        XCTAssertTrue(OpusDecoder.isOpusFile(URL(fileURLWithPath: "/path/to/file.OPUS")))
    }
    #endif

    // MARK: - OGGDecoder with non-existent files

    func testOGGDecodeNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.ogg")
        XCTAssertThrowsError(try OGGDecoder.decode(url: url)) { error in
            guard case OGGDecoder.OGGError.failedToOpen = error else {
                XCTFail("Expected failedToOpen error, got \(error)")
                return
            }
        }
    }

    func testOGGDurationNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.ogg")
        let duration = OGGDecoder.duration(url: url)
        XCTAssertEqual(duration, 0)
    }

    func testOGGFileInfoNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.ogg")
        let info = OGGDecoder.fileInfo(url: url)
        XCTAssertNil(info)
    }

    // MARK: - OpusDecoder with non-existent files

    func testOpusDecodeNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.opus")
        XCTAssertThrowsError(try OpusDecoder.decode(url: url)) { error in
            guard case OpusDecoder.OpusError.failedToOpen = error else {
                XCTFail("Expected failedToOpen error, got \(error)")
                return
            }
        }
    }

    func testOpusDurationNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.opus")
        let duration = OpusDecoder.duration(url: url)
        XCTAssertEqual(duration, 0)
    }

    func testOpusFileInfoNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.opus")
        let info = OpusDecoder.fileInfo(url: url)
        XCTAssertNil(info)
    }

    // MARK: - OGG convertToCAF error path

    func testOGGConvertToCAFNonExistentFile() {
        let url = URL(fileURLWithPath: "/nonexistent/path/test.ogg")
        XCTAssertThrowsError(try OGGDecoder.convertToCAF(url: url))
    }

    // MARK: - Metadata Service format detection with codecs

    func testOpusIsSupportedAudioFile() {
        XCTAssertTrue(MetadataService.isSupportedAudioFile(URL(fileURLWithPath: "/test.opus")))
    }

    func testOGGIsSupportedAudioFile() {
        XCTAssertTrue(MetadataService.isSupportedAudioFile(URL(fileURLWithPath: "/test.ogg")))
    }
}
