//
//  MockURLSession.swift
//  suixinkanTests
//

import Foundation
@testable import suixinkan

/// 按顺序返回预设响应的 URLSession 测试替身。
final class MockURLSession: URLSessionProtocol {
    private(set) var requests: [URLRequest] = []
    private var responses: [Result<(Data, URLResponse), Error>]
    private var responseIndex = 0

    init(responses: [Data], statusCode: Int = 200) {
        self.responses = responses.map { data in
            .success((
                data,
                HTTPURLResponse(
                    url: URL(string: "https://api-test.zhifly.cn/mock")!,
                    statusCode: statusCode,
                    httpVersion: nil,
                    headerFields: nil
                )!
            ))
        }
    }

    init(results: [Result<(Data, URLResponse), Error>]) {
        self.responses = results
    }

    func data(for request: URLRequest) async throws -> (Data, URLResponse) {
        requests.append(request)
        guard responseIndex < responses.count else {
            throw URLError(.badServerResponse)
        }
        defer { responseIndex += 1 }
        return try responses[responseIndex].get()
    }
}

enum TestJSON {
    static func envelope<T: Encodable>(data: T) throws -> Data {
        let payload = try JSONEncoder().encode(data)
        let payloadObject = try JSONSerialization.jsonObject(with: payload)
        let envelope: [String: Any] = [
            "code": 100000,
            "msg": "success",
            "data": payloadObject,
        ]
        return try JSONSerialization.data(withJSONObject: envelope)
    }

    static func errorEnvelope(code: Int, msg: String) throws -> Data {
        let envelope: [String: Any] = [
            "code": code,
            "msg": msg,
            "data": NSNull(),
        ]
        return try JSONSerialization.data(withJSONObject: envelope)
    }
}
