import Foundation

public class SetupCache<T: FFTElement> : @unchecked Sendable {
    typealias FFTType = FFT<T>
    private var cache: [Int: FFT<T>] = [:]

    private let queue = DispatchQueue(label: String(describing: SetupCache.self), attributes: .concurrent)

    public init() {}

    public func get(for n: Int) throws -> FFT<T> {
        var setup: FFTType??
        queue.sync {
            setup = cache[n]
        }
        if setup == nil {
            queue.sync(flags: .barrier) {
                setup = cache[n]
                if setup == nil {
                    let entry = try? FFTType(n: n)
                    cache[n] = entry
                    setup = entry
                }
            }
        }
        guard let s = setup! else { throw FFTError.invalidSize }
        return s
    }

    public func clear() {
        queue.sync(flags: .barrier) {
            cache.removeAll()
        }
    }
}
