// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon

import Foundation

#if os(iOS)
  import Flutter
#elseif os(macOS)
  import FlutterMacOS
#else
  #error("Unsupported platform.")
#endif

/// Error class for passing custom error details to Dart side.
final class PigeonError: Error {
  let code: String
  let message: String?
  let details: Sendable?

  init(code: String, message: String?, details: Sendable?) {
    self.code = code
    self.message = message
    self.details = details
  }

  var localizedDescription: String {
    return
      "PigeonError(code: \(code), message: \(message ?? "<nil>"), details: \(details ?? "<nil>")"
  }
}

private func wrapResult(_ result: Any?) -> [Any?] {
  return [result]
}

private func wrapError(_ error: Any) -> [Any?] {
  if let pigeonError = error as? PigeonError {
    return [
      pigeonError.code,
      pigeonError.message,
      pigeonError.details,
    ]
  }
  if let flutterError = error as? FlutterError {
    return [
      flutterError.code,
      flutterError.message,
      flutterError.details,
    ]
  }
  return [
    "\(error)",
    "\(Swift.type(of: error))",
    "Stacktrace: \(Thread.callStackSymbols)",
  ]
}

private func isNullish(_ value: Any?) -> Bool {
  return value is NSNull || value == nil
}

private func nilOrValue<T>(_ value: Any?) -> T? {
  if value is NSNull { return nil }
  return value as! T?
}

private func doubleEqualsVideoPlayerPluginMessages(_ lhs: Double, _ rhs: Double) -> Bool {
  return (lhs.isNaN && rhs.isNaN) || lhs == rhs
}

private func doubleHashVideoPlayerPluginMessages(_ value: Double, _ hasher: inout Hasher) {
  if value.isNaN {
    hasher.combine(0x7FF8_0000_0000_0000)
  } else {
    // Normalize -0.0 to 0.0
    hasher.combine(value == 0 ? 0 : value)
  }
}

func deepEqualsVideoPlayerPluginMessages(_ lhs: Any?, _ rhs: Any?) -> Bool {
  let cleanLhs = nilOrValue(lhs) as Any?
  let cleanRhs = nilOrValue(rhs) as Any?
  switch (cleanLhs, cleanRhs) {
  case (nil, nil):
    return true

  case (nil, _), (_, nil):
    return false

  case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs:
    return true

  case is (Void, Void):
    return true

  case (let lhsArray, let rhsArray) as ([Any?], [Any?]):
    guard lhsArray.count == rhsArray.count else { return false }
    for (index, element) in lhsArray.enumerated() {
      if !deepEqualsVideoPlayerPluginMessages(element, rhsArray[index]) {
        return false
      }
    }
    return true

  case (let lhsArray, let rhsArray) as ([Double], [Double]):
    guard lhsArray.count == rhsArray.count else { return false }
    for (index, element) in lhsArray.enumerated() {
      if !doubleEqualsVideoPlayerPluginMessages(element, rhsArray[index]) {
        return false
      }
    }
    return true

  case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
    guard lhsDictionary.count == rhsDictionary.count else { return false }
    for (lhsKey, lhsValue) in lhsDictionary {
      var found = false
      for (rhsKey, rhsValue) in rhsDictionary {
        if deepEqualsVideoPlayerPluginMessages(lhsKey, rhsKey) {
          if deepEqualsVideoPlayerPluginMessages(lhsValue, rhsValue) {
            found = true
            break
          } else {
            return false
          }
        }
      }
      if !found { return false }
    }
    return true

  case (let lhs as Double, let rhs as Double):
    return doubleEqualsVideoPlayerPluginMessages(lhs, rhs)

  case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable):
    return lhsHashable == rhsHashable

  default:
    return false
  }
}

func deepHashVideoPlayerPluginMessages(value: Any?, hasher: inout Hasher) {
  let cleanValue = nilOrValue(value) as Any?
  if let cleanValue = cleanValue {
    if let doubleValue = cleanValue as? Double {
      doubleHashVideoPlayerPluginMessages(doubleValue, &hasher)
    } else if let valueList = cleanValue as? [Any?] {
      for item in valueList {
        deepHashVideoPlayerPluginMessages(value: item, hasher: &hasher)
      }
    } else if let valueList = cleanValue as? [Double] {
      for item in valueList {
        doubleHashVideoPlayerPluginMessages(item, &hasher)
      }
    } else if let valueDict = cleanValue as? [AnyHashable: Any?] {
      var result = 0
      for (key, value) in valueDict {
        var entryKeyHasher = Hasher()
        deepHashVideoPlayerPluginMessages(value: key, hasher: &entryKeyHasher)
        var entryValueHasher = Hasher()
        deepHashVideoPlayerPluginMessages(value: value, hasher: &entryValueHasher)
        result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize())
      }
      hasher.combine(result)
    } else if let hashableValue = cleanValue as? AnyHashable {
      hasher.combine(hashableValue)
    } else {
      hasher.combine(String(describing: cleanValue))
    }
  } else {
    hasher.combine(0)
  }
}

/// Information passed to the platform view creation.
///
/// Generated class from Pigeon that represents data sent in messages.
struct PlatformVideoViewCreationParams: Hashable {
  var playerId: Int64

  // swift-format-ignore: AlwaysUseLowerCamelCase
  static func fromList(_ pigeonVar_list: [Any?]) -> PlatformVideoViewCreationParams? {
    let playerId = pigeonVar_list[0] as! Int64

    return PlatformVideoViewCreationParams(
      playerId: playerId
    )
  }
  func toList() -> [Any?] {
    return [
      playerId
    ]
  }
  static func == (lhs: PlatformVideoViewCreationParams, rhs: PlatformVideoViewCreationParams)
    -> Bool
  {
    if Swift.type(of: lhs) != Swift.type(of: rhs) {
      return false
    }
    return deepEqualsVideoPlayerPluginMessages(lhs.playerId, rhs.playerId)
  }

  func hash(into hasher: inout Hasher) {
    hasher.combine("PlatformVideoViewCreationParams")
    deepHashVideoPlayerPluginMessages(value: playerId, hasher: &hasher)
  }
}

/// Generated class from Pigeon that represents data sent in messages.
struct CreationOptions: Hashable {
  var uri: String
  var httpHeaders: [String: String]

  // swift-format-ignore: AlwaysUseLowerCamelCase
  static func fromList(_ pigeonVar_list: [Any?]) -> CreationOptions? {
    let uri = pigeonVar_list[0] as! String
    let httpHeaders = pigeonVar_list[1] as! [String: String]

    return CreationOptions(
      uri: uri,
      httpHeaders: httpHeaders
    )
  }
  func toList() -> [Any?] {
    return [
      uri,
      httpHeaders,
    ]
  }
  static func == (lhs: CreationOptions, rhs: CreationOptions) -> Bool {
    if Swift.type(of: lhs) != Swift.type(of: rhs) {
      return false
    }
    return deepEqualsVideoPlayerPluginMessages(lhs.uri, rhs.uri)
      && deepEqualsVideoPlayerPluginMessages(lhs.httpHeaders, rhs.httpHeaders)
  }

  func hash(into hasher: inout Hasher) {
    hasher.combine("CreationOptions")
    deepHashVideoPlayerPluginMessages(value: uri, hasher: &hasher)
    deepHashVideoPlayerPluginMessages(value: httpHeaders, hasher: &hasher)
  }
}

/// Generated class from Pigeon that represents data sent in messages.
struct TexturePlayerIds: Hashable {
  var playerId: Int64
  var textureId: Int64

  // swift-format-ignore: AlwaysUseLowerCamelCase
  static func fromList(_ pigeonVar_list: [Any?]) -> TexturePlayerIds? {
    let playerId = pigeonVar_list[0] as! Int64
    let textureId = pigeonVar_list[1] as! Int64

    return TexturePlayerIds(
      playerId: playerId,
      textureId: textureId
    )
  }
  func toList() -> [Any?] {
    return [
      playerId,
      textureId,
    ]
  }
  static func == (lhs: TexturePlayerIds, rhs: TexturePlayerIds) -> Bool {
    if Swift.type(of: lhs) != Swift.type(of: rhs) {
      return false
    }
    return deepEqualsVideoPlayerPluginMessages(lhs.playerId, rhs.playerId)
      && deepEqualsVideoPlayerPluginMessages(lhs.textureId, rhs.textureId)
  }

  func hash(into hasher: inout Hasher) {
    hasher.combine("TexturePlayerIds")
    deepHashVideoPlayerPluginMessages(value: playerId, hasher: &hasher)
    deepHashVideoPlayerPluginMessages(value: textureId, hasher: &hasher)
  }
}

private class VideoPlayerPluginMessagesPigeonCodecReader: FlutterStandardReader {
  override func readValue(ofType type: UInt8) -> Any? {
    switch type {
    case 129:
      return PlatformVideoViewCreationParams.fromList(self.readValue() as! [Any?])
    case 130:
      return CreationOptions.fromList(self.readValue() as! [Any?])
    case 131:
      return TexturePlayerIds.fromList(self.readValue() as! [Any?])
    default:
      return super.readValue(ofType: type)
    }
  }
}

private class VideoPlayerPluginMessagesPigeonCodecWriter: FlutterStandardWriter {
  override func writeValue(_ value: Any) {
    if let value = value as? PlatformVideoViewCreationParams {
      super.writeByte(129)
      super.writeValue(value.toList())
    } else if let value = value as? CreationOptions {
      super.writeByte(130)
      super.writeValue(value.toList())
    } else if let value = value as? TexturePlayerIds {
      super.writeByte(131)
      super.writeValue(value.toList())
    } else {
      super.writeValue(value)
    }
  }
}

private class VideoPlayerPluginMessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter {
  override func reader(with data: Data) -> FlutterStandardReader {
    return VideoPlayerPluginMessagesPigeonCodecReader(data: data)
  }

  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
    return VideoPlayerPluginMessagesPigeonCodecWriter(data: data)
  }
}

class VideoPlayerPluginMessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
  static let shared = VideoPlayerPluginMessagesPigeonCodec(
    readerWriter: VideoPlayerPluginMessagesPigeonCodecReaderWriter())
}

/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol AVFoundationVideoPlayerApi {
  func initialize() throws
  func createPlatformViewPlayer(options params: CreationOptions) throws -> Int64
  func createTexturePlayer(options creationOptions: CreationOptions) throws -> TexturePlayerIds
  func setMixWithOthers(_ mixWithOthers: Bool) throws
  func fileURLForAsset(name asset: String, package: String?) throws -> String?
}

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class AVFoundationVideoPlayerApiSetup {
  static var codec: FlutterStandardMessageCodec { VideoPlayerPluginMessagesPigeonCodec.shared }
  /// Sets up an instance of `AVFoundationVideoPlayerApi` to handle messages through the `binaryMessenger`.
  static func setUp(
    binaryMessenger: FlutterBinaryMessenger, api: AVFoundationVideoPlayerApi?,
    messageChannelSuffix: String = ""
  ) {
    let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : ""
    let initializeChannel = FlutterBasicMessageChannel(
      name:
        "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize\(channelSuffix)",
      binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      initializeChannel.setMessageHandler { _, reply in
        do {
          try api.initialize()
          reply(wrapResult(nil))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      initializeChannel.setMessageHandler(nil)
    }
    let createForPlatformViewChannel = FlutterBasicMessageChannel(
      name:
        "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForPlatformView\(channelSuffix)",
      binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      createForPlatformViewChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let paramsArg = args[0] as! CreationOptions
        do {
          let result = try api.createPlatformViewPlayer(options: paramsArg)
          reply(wrapResult(result))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      createForPlatformViewChannel.setMessageHandler(nil)
    }
    let createForTextureViewChannel = FlutterBasicMessageChannel(
      name:
        "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForTextureView\(channelSuffix)",
      binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      createForTextureViewChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let creationOptionsArg = args[0] as! CreationOptions
        do {
          let result = try api.createTexturePlayer(options: creationOptionsArg)
          reply(wrapResult(result))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      createForTextureViewChannel.setMessageHandler(nil)
    }
    let setMixWithOthersChannel = FlutterBasicMessageChannel(
      name:
        "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers\(channelSuffix)",
      binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      setMixWithOthersChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let mixWithOthersArg = args[0] as! Bool
        do {
          try api.setMixWithOthers(mixWithOthersArg)
          reply(wrapResult(nil))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      setMixWithOthersChannel.setMessageHandler(nil)
    }
    let getAssetUrlChannel = FlutterBasicMessageChannel(
      name:
        "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getAssetUrl\(channelSuffix)",
      binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      getAssetUrlChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let assetArg = args[0] as! String
        let packageArg: String? = nilOrValue(args[1])
        do {
          let result = try api.fileURLForAsset(name: assetArg, package: packageArg)
          reply(wrapResult(result))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      getAssetUrlChannel.setMessageHandler(nil)
    }
  }
}
