import Foundation

class EXDevLauncherRemoteLogsManager {
  private var batch: [String] = []
  private let url: URL

  init(withUrl url: URL) {
    self.url = url
  }

  func deferError(exception: NSException) {
    batch.append("\(exception.name.rawValue): \(exception.reason ?? exception.description)")
    batch.append("  \(exception.callStackSymbols.joined(separator: "\n  "))")
  }

  func deferError(message: String) {
    batch.append(message)
  }

  func sendSync() {
    // message format comes from
    // https://github.com/facebook/react-native/blob/0.69-stable/Libraries/Utilities/HMRClient.js#L119-L134
    let messageJson = [
      "type": "log",
      "level": "error",
      "mode": "BRIDGE",
      // `data` is an array whose members are simply concatenated with a space before printing to
      // the console, so we join messages with a newline and send an array consisting of just a
      // single item.
      "data": [batch.joined(separator: "\n")]
    ] as [String: Any]
    guard let data = try? JSONSerialization.data(withJSONObject: messageJson, options: []) else {
      batch.removeAll()
      return
    }

    batch.removeAll()

    let group = DispatchGroup()
    group.enter()

    let task = URLSession.shared.webSocketTask(with: self.url)
    task.resume()

    guard let dataString = String(data: data, encoding: .utf8) else {
      group.leave()
      return
    }
    let message = URLSessionWebSocketTask.Message.string(dataString)
    task.send(message) { _ in
      group.leave()
    }
    _ = group.wait(timeout: DispatchTime.now() + .seconds(2))
  }
}
