//
//  UMengSDKBootstrapTests.swift
//  suixinkanTests
//
//  Created by Codex on 2026/7/2.
//

import XCTest
@testable import suixinkan

@MainActor
/// 友盟 SDK 隐私门禁测试，覆盖初始化时机和 APM 最小合规配置。
final class UMengSDKBootstrapTests: XCTestCase {
    /// 测试未同意隐私政策时不会初始化友盟。
    func testConfigureIfAllowedSkipsWhenPrivacyNotAccepted() {
        let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
        let configurator = RecordingUMengConfigurator()
        let bootstrap = UMengSDKBootstrap(configurator: configurator)

        let didConfigure = bootstrap.configureIfAllowed(
            preferencesStore: preferences,
            appKey: "app-key",
            channel: "App Store"
        )

        XCTAssertFalse(didConfigure)
        XCTAssertTrue(configurator.calls.isEmpty)
    }

    /// 测试已同意隐私但 AppKey 为空时不会初始化友盟。
    func testConfigureIfAllowedSkipsWhenAppKeyIsBlank() {
        let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
        preferences.savePrivacyAgreementAccepted(true)
        let configurator = RecordingUMengConfigurator()
        let bootstrap = UMengSDKBootstrap(configurator: configurator)

        let didConfigure = bootstrap.configureIfAllowed(
            preferencesStore: preferences,
            appKey: "   ",
            channel: "App Store"
        )

        XCTAssertFalse(didConfigure)
        XCTAssertTrue(configurator.calls.isEmpty)
    }

    /// 测试隐私已同意且 AppKey 有效时只初始化一次。
    func testConfigureIfAllowedConfiguresOnceWhenAllowed() {
        let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
        preferences.savePrivacyAgreementAccepted(true)
        let configurator = RecordingUMengConfigurator()
        let bootstrap = UMengSDKBootstrap(configurator: configurator)

        let firstResult = bootstrap.configureIfAllowed(
            preferencesStore: preferences,
            appKey: " app-key ",
            channel: " App Store "
        )
        let secondResult = bootstrap.configureIfAllowed(
            preferencesStore: preferences,
            appKey: "app-key",
            channel: "App Store"
        )

        XCTAssertTrue(firstResult)
        XCTAssertFalse(secondResult)
        XCTAssertEqual(configurator.calls.count, 1)
        XCTAssertEqual(configurator.calls.first?.appKey, "app-key")
        XCTAssertEqual(configurator.calls.first?.channel, "App Store")
    }

    /// 测试默认 APM 配置为崩溃、卡顿、启动开启，网络、内存、OOM、日志回捞关闭。
    func testConfigureIfAllowedUsesMinimumComplianceAPMOptions() {
        let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
        preferences.savePrivacyAgreementAccepted(true)
        let configurator = RecordingUMengConfigurator()
        let bootstrap = UMengSDKBootstrap(configurator: configurator)

        bootstrap.configureIfAllowed(
            preferencesStore: preferences,
            appKey: "app-key",
            channel: nil
        )

        XCTAssertEqual(configurator.calls.first?.options, .minimumCompliance)
        XCTAssertTrue(UMengAPMOptions.minimumCompliance.crashAndBlockMonitorEnable)
        XCTAssertTrue(UMengAPMOptions.minimumCompliance.launchMonitorEnable)
        XCTAssertFalse(UMengAPMOptions.minimumCompliance.networkEnable)
        XCTAssertFalse(UMengAPMOptions.minimumCompliance.memMonitorEnable)
        XCTAssertFalse(UMengAPMOptions.minimumCompliance.oomMonitorEnable)
        XCTAssertFalse(UMengAPMOptions.minimumCompliance.logCollectEnable)
    }

    private func makeIsolatedDefaults() -> UserDefaults {
        let suiteName = "UMengSDKBootstrapTests.\(UUID().uuidString)"
        let defaults = UserDefaults(suiteName: suiteName)!
        defaults.removePersistentDomain(forName: suiteName)
        return defaults
    }
}

/// 友盟配置器测试替身，记录初始化请求。
@MainActor
private final class RecordingUMengConfigurator: UMengSDKConfiguring {
    private(set) var calls: [Call] = []

    /// 记录一次友盟初始化参数。
    func configure(appKey: String, channel: String?, options: UMengAPMOptions) {
        calls.append(Call(appKey: appKey, channel: channel, options: options))
    }

    /// 单次友盟初始化调用记录。
    struct Call: Equatable {
        let appKey: String
        let channel: String?
        let options: UMengAPMOptions
    }
}
