import Foundation
import XCTest

@MainActor
extension XCUIApplication {

    /// Launch with a freshly-fetched pairing URL so the test starts from a
    /// known paired state. Hits `/pair-qr` on the sidecar to obtain a
    /// one-time-use token, then passes it to the app via launch args.
    /// Fails the current test if the sidecar is unreachable.
    func launchPaired(file: StaticString = #file, line: UInt = #line) {
        guard let url = TestSidecar.freshPairURL() else {
            XCTFail("Could not fetch fresh pair URL from sidecar — is it running?",
                    file: file, line: line)
            return
        }
        launchArguments = ["--uitest", "--reset-state", "--pair-with-url", url]
        launch()
    }

    /// Launch with state reset so the PairingFlowView is shown.
    func launchUnpaired() {
        launchArguments = ["--uitest", "--reset-state"]
        launch()
    }

    /// Launch with a specific pairing URL (for the explicit deep-link test).
    func launchWithPairing(url: String) {
        launchArguments = ["--uitest", "--reset-state", "--pair-with-url", url]
        launch()
    }

    /// Launch directly into the lock screen (faceid enabled + forced lock).
    /// Resets state first so the test isn't polluted by previous runs.
    func launchLocked() {
        launchArguments = ["--uitest", "--reset-state", "--enable-faceid", "--force-lock"]
        launch()
    }
}

// MARK: - Sidecar helpers

enum TestSidecar {
    static let baseURL = "http://10.13.37.2:17373"
    static let bearer  = "GeoZytsPPGwItCHRNu8EwoZGlHH5iUAx"

    /// Synchronously fetch a fresh pairing URL from the sidecar.
    static func freshPairURL() -> String? {
        let url = URL(string: "\(baseURL)/pair-qr?token=\(bearer)&format=url")!
        var result: String?
        let sem = DispatchSemaphore(value: 0)
        URLSession.shared.dataTask(with: url) { data, _, _ in
            defer { sem.signal() }
            guard let data = data,
                  let text = String(data: data, encoding: .utf8) else { return }
            if let match = text.range(of: #"pi-remote://[^\s]+"#,
                                      options: .regularExpression) {
                result = String(text[match])
            }
        }.resume()
        _ = sem.wait(timeout: .now() + 5)
        return result
    }

    /// Delete a session via the sidecar REST API (best-effort, for cleanup).
    static func deleteSession(_ id: String) {
        var req = URLRequest(url: URL(string: "\(baseURL)/sessions/\(id)")!)
        req.httpMethod = "DELETE"
        req.setValue("Bearer \(bearer)", forHTTPHeaderField: "Authorization")
        let sem = DispatchSemaphore(value: 0)
        URLSession.shared.dataTask(with: req) { _, _, _ in sem.signal() }.resume()
        _ = sem.wait(timeout: .now() + 5)
    }
}
