//
//  RateLimiterTests.swift
//  SportsTimeTests
//
//  TDD specification tests for RateLimiter types.
//

import Testing
import Foundation
@testable import SportsTime

// MARK: - ProviderConfig Tests

@Suite("ProviderConfig")
struct ProviderConfigTests {

    // MARK: - Specification Tests: Properties

    @Test("ProviderConfig: stores name")
    func providerConfig_name() {
        let config = RateLimiter.ProviderConfig(
            name: "test_provider",
            minInterval: 1.0,
            burstLimit: 10,
            burstWindow: 60
        )
        #expect(config.name == "test_provider")
    }

    @Test("ProviderConfig: stores minInterval")
    func providerConfig_minInterval() {
        let config = RateLimiter.ProviderConfig(
            name: "test",
            minInterval: 0.5,
            burstLimit: 10,
            burstWindow: 60
        )
        #expect(config.minInterval == 0.5)
    }

    @Test("ProviderConfig: stores burstLimit")
    func providerConfig_burstLimit() {
        let config = RateLimiter.ProviderConfig(
            name: "test",
            minInterval: 1.0,
            burstLimit: 25,
            burstWindow: 60
        )
        #expect(config.burstLimit == 25)
    }

    @Test("ProviderConfig: stores burstWindow")
    func providerConfig_burstWindow() {
        let config = RateLimiter.ProviderConfig(
            name: "test",
            minInterval: 1.0,
            burstLimit: 10,
            burstWindow: 120
        )
        #expect(config.burstWindow == 120)
    }

    // MARK: - Edge Cases

    @Test("ProviderConfig: handles zero minInterval")
    func providerConfig_zeroMinInterval() {
        let config = RateLimiter.ProviderConfig(
            name: "fast",
            minInterval: 0,
            burstLimit: 100,
            burstWindow: 60
        )
        #expect(config.minInterval == 0)
    }

    @Test("ProviderConfig: handles large burstLimit")
    func providerConfig_largeBurstLimit() {
        let config = RateLimiter.ProviderConfig(
            name: "generous",
            minInterval: 0.1,
            burstLimit: 1000,
            burstWindow: 60
        )
        #expect(config.burstLimit == 1000)
    }

    @Test("ProviderConfig: handles fractional values")
    func providerConfig_fractionalValues() {
        let config = RateLimiter.ProviderConfig(
            name: "precise",
            minInterval: 0.333,
            burstLimit: 15,
            burstWindow: 30.5
        )
        #expect(config.minInterval == 0.333)
        #expect(config.burstWindow == 30.5)
    }

    // MARK: - Invariant Tests

    /// - Invariant: All properties are stored exactly as provided
    @Test("Invariant: properties stored exactly as provided")
    func invariant_propertiesStoredExactly() {
        let testCases: [(name: String, minInterval: TimeInterval, burstLimit: Int, burstWindow: TimeInterval)] = [
            ("mlb", 0.1, 30, 60),
            ("nba", 0.5, 10, 60),
            ("slow", 5.0, 5, 120),
            ("unlimited", 0, 1000, 1)
        ]

        for (name, interval, limit, window) in testCases {
            let config = RateLimiter.ProviderConfig(
                name: name,
                minInterval: interval,
                burstLimit: limit,
                burstWindow: window
            )
            #expect(config.name == name)
            #expect(config.minInterval == interval)
            #expect(config.burstLimit == limit)
            #expect(config.burstWindow == window)
        }
    }
}
