import Foundation

public enum PCM16LE {
    public static func encode(samples: [Float]) -> Data {
        var data = Data()
        data.reserveCapacity(samples.count * MemoryLayout<Int16>.size)

        for sample in samples {
            let clamped = max(-1.0, min(1.0, sample))
            let scaled: Int16

            if clamped >= 1.0 {
                scaled = Int16.max
            } else if clamped <= -1.0 {
                scaled = Int16.min
            } else {
                scaled = Int16((clamped * Float(Int16.max)).rounded())
            }

            var littleEndian = scaled.littleEndian
            withUnsafeBytes(of: &littleEndian) { bytes in
                data.append(contentsOf: bytes)
            }
        }

        return data
    }

    public static func resampleLinear(samples: [Float], sourceRate: Int, targetRate: Int = 16_000) -> [Float] {
        guard sourceRate > 0, targetRate > 0, !samples.isEmpty else {
            return []
        }

        guard sourceRate != targetRate else {
            return samples
        }

        let ratio = Double(sourceRate) / Double(targetRate)
        let outputCount = max(1, Int(Double(samples.count) / ratio))

        return (0..<outputCount).map { index in
            let sourcePosition = Double(index) * ratio
            let lowerIndex = Int(sourcePosition)
            let upperIndex = min(lowerIndex + 1, samples.count - 1)
            let fraction = Float(sourcePosition - Double(lowerIndex))
            let lower = samples[min(lowerIndex, samples.count - 1)]
            let upper = samples[upperIndex]
            return lower + ((upper - lower) * fraction)
        }
    }
}
