//
//  CloudDriveAPITests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

@MainActor
/// 相册云盘 API 测试。
final class CloudDriveAPITests: XCTestCase {
    func testCloudDriveRequestsMatchAndroidPaths() async throws {
        let session = MockURLSession(responses: [
            envelopeJSON(#"{"total":0,"list":[]}"#),
            envelopeJSON("{}"),
            envelopeJSON("{}"),
            envelopeJSON("{}"),
            envelopeJSON("{}"),
            envelopeJSON(#"{"can_upload":false,"reason":"空间不足"}"#),
            envelopeJSON("{}"),
            envelopeJSON("{}"),
        ])
        let api = CloudDriveAPI(client: APIClient(environment: .testing, session: session))

        _ = try await api.cloudFileList(parentFolderId: 4, name: "abc", type: 2, orderBy: 1, page: 3, pageSize: 20)
        try await api.createCloudFolder(parentFolderId: 4, name: "新文件夹")
        try await api.uploadCloudFile(parentFolderId: 4, fileUrl: "https://cdn/a.jpg", fileName: "a.jpg")
        try await api.deleteCloudFiles(CloudFileDeleteRequest(list: [CloudFileOperationItem(id: 7, type: 2)]))
        try await api.moveCloudFiles(CloudFileMoveRequest(targetFolderId: 9, list: [CloudFileOperationItem(id: 7, type: 2)]))
        _ = try await api.checkUploadPermission()
        try await api.modifyCloudFolderName(fileId: 8, name: "目录")
        try await api.modifyCloudFileName(fileId: 7, fileName: "b.jpg")

        XCTAssertEqual(session.requests[0].httpMethod, "GET")
        XCTAssertEqual(session.requests[0].url?.path, "/api/yf-handset-app/photog/cloud-driver/list")
        let query = URLComponents(url: session.requests[0].url!, resolvingAgainstBaseURL: false)?.queryItems
        XCTAssertEqual(query?.first { $0.name == "parent_folder_id" }?.value, "4")
        XCTAssertEqual(query?.first { $0.name == "name" }?.value, "abc")
        XCTAssertEqual(query?.first { $0.name == "type" }?.value, "2")
        XCTAssertEqual(query?.first { $0.name == "order_by" }?.value, "1")
        XCTAssertEqual(query?.first { $0.name == "page" }?.value, "3")

        XCTAssertEqual(session.requests[1].url?.path, "/api/yf-handset-app/photog/cloud-driver/folder-create")
        let folderBody = try bodyObject(session.requests[1])
        XCTAssertEqual(folderBody["parent_folder_id"] as? Int, 4)
        XCTAssertEqual(folderBody["name"] as? String, "新文件夹")

        XCTAssertEqual(session.requests[2].url?.path, "/api/yf-handset-app/photog/cloud-driver/file-upload")
        let uploadBody = try bodyObject(session.requests[2])
        XCTAssertEqual(uploadBody["file_url"] as? String, "https://cdn/a.jpg")
        XCTAssertEqual(uploadBody["file_name"] as? String, "a.jpg")

        XCTAssertEqual(session.requests[3].url?.path, "/api/yf-handset-app/photog/cloud-driver/delete")
        XCTAssertEqual(session.requests[4].url?.path, "/api/yf-handset-app/photog/cloud-driver/move")
        let moveBody = try bodyObject(session.requests[4])
        XCTAssertEqual(moveBody["target_folder_id"] as? Int, 9)
        XCTAssertEqual(session.requests[5].url?.path, "/api/yf-handset-app/photog/cloud-driver/check-upload-permission")
        XCTAssertEqual(session.requests[6].url?.path, "/api/yf-handset-app/photog/cloud-driver/folder-edit")
        XCTAssertEqual(session.requests[7].url?.path, "/api/yf-handset-app/photog/cloud-driver/file-edit")
    }

    private func bodyObject(_ request: URLRequest) throws -> [String: Any] {
        try XCTUnwrap(JSONSerialization.jsonObject(with: XCTUnwrap(request.httpBody)) as? [String: Any])
    }

    private func envelopeJSON(_ dataJSON: String) -> Data {
        """
        {"code":100000,"msg":"success","data":\(dataJSON)}
        """.data(using: .utf8)!
    }
}
