// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Provides access to the
/// [Foundation URL Loading System](https://developer.apple.com/documentation/foundation/url_loading_system).
///
/// For example:
/// ```
/// void main() {
///   final url = Uri.https('www.example.com', '/');
///   final session = URLSession.sharedSession();
///   final task = session.dataTaskWithCompletionHandler(
///     URLRequest.fromUrl(url),
///       (data, response, error) {
///     if (error == null) {
///       if (response != null && response.statusCode == 200) {
///         print(response);  // Do something with the response.
///         return;
///       }
///     }
///     print(error);  // Handle errors.
///   });
///   task.resume();
/// }
/// ```
library;

import 'dart:async';
import 'dart:ffi';
import 'dart:isolate';
import 'dart:math';
import 'dart:typed_data';

import 'package:async/async.dart';
import 'package:ffi/ffi.dart';

import 'native_cupertino_bindings.dart' as ncb;
import 'utils.dart';

abstract class _ObjectHolder<T extends ncb.NSObject> {
  final T _nsObject;

  _ObjectHolder(this._nsObject);

  @override
  bool operator ==(Object other) {
    if (other is _ObjectHolder) {
      return _nsObject == other._nsObject;
    }
    return false;
  }

  @override
  int get hashCode => _nsObject.hashCode;
}

/// Settings for controlling whether cookies will be accepted.
///
/// See [HTTPCookieAcceptPolicy](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1408933-httpcookieacceptpolicy).
enum HTTPCookieAcceptPolicy {
  httpCookieAcceptPolicyAlways,
  httpCookieAcceptPolicyNever,
  httpCookieAcceptPolicyOnlyFromMainDocumentDomain,
}

/// Controls how response data is cached.
///
/// See [URLRequestCachePolicy](https://developer.apple.com/documentation/foundation/nsurlrequestcachepolicy).
enum URLRequestCachePolicy {
  useProtocolCachePolicy,
  reloadIgnoringLocalCacheData,
  returnCacheDataElseLoad,
  returnCacheDataDontLoad,
  reloadIgnoringLocalAndRemoteCacheData,
  reloadRevalidatingCacheData,
}

// Controls how multipath TCP should be used.
//
// See [NSURLSessionMultipathServiceType](https://developer.apple.com/documentation/foundation/nsurlsessionmultipathservicetype).
enum URLSessionMultipathServiceType {
  multipathServiceTypeNone,
  multipathServiceTypeHandover,
  multipathServiceTypeInteractive,
  multipathServiceTypeAggregate,
}

/// Controls how [URLSessionTask] execute will proceed after the response is
/// received.
///
/// See [NSURLSessionResponseDisposition](https://developer.apple.com/documentation/foundation/nsurlsessionresponsedisposition).
enum URLSessionResponseDisposition {
  urlSessionResponseCancel,
  urlSessionResponseAllow,
  urlSessionResponseBecomeDownload,
  urlSessionResponseBecomeStream
}

/// Provides in indication to the operating system on what type of requests
/// are being sent.
///
/// See [NSURLRequestNetworkServiceType](https://developer.apple.com/documentation/foundation/nsurlrequestnetworkservicetype).
enum URLRequestNetworkService {
  networkServiceTypeDefault,
  networkServiceTypeVoIP,
  networkServiceTypeVideo,
  networkServiceTypeBackground,
  networkServiceTypeVoice,
  networkServiceTypeResponsiveData,
  networkServiceTypeAVStreaming,
  networkServiceTypeResponsiveAV,
  networkServiceTypeCallSignaling
}

/// The type of a WebSocket message i.e. text or data.
///
/// See [NSURLSessionWebSocketMessageType](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessagetype)
enum URLSessionWebSocketMessageType {
  urlSessionWebSocketMessageTypeData,
  urlSessionWebSocketMessageTypeString,
}

ncb.NSInputStream _streamToNSInputStream(Stream<List<int>> stream) {
  const maxReadAheadSize = 4096;
  final queue = StreamQueue(stream);
  final port = ReceivePort();
  final inputStream = ncb.CUPHTTPStreamToNSInputStreamAdapter.alloc(helperLibs)
      .initWithPort_(port.sendPort.nativePort);

  late StreamSubscription<dynamic> s;
  // Messages from `CUPHTTPStreamToNSInputStreamAdapter` indicate that the task
  // is attempting to read more data but there is none available.
  s = port.listen((_) async {
    if (inputStream.streamStatus == ncb.NSStreamStatus.NSStreamStatusClosed) {
      return;
    }

    // Prevent multiple executions of this code to be in flight at once.
    s.pause();
    while (await queue.hasNext &&
        inputStream.streamStatus != ncb.NSStreamStatus.NSStreamStatusClosed) {
      late final List<int> next;
      try {
        next = await queue.next;
      } catch (e) {
        inputStream.setError_(Error.fromCustomDomain('DartError', 0,
                localizedDescription: e.toString())
            ._nsObject);
        break;
      }
      // In practice the read length request will be large (>1MB) so,
      // instead of adding that much data, try to keep the buffer
      // at least `maxReadAheadSize`.
      if (inputStream.addData_(Data.fromList(next)._nsObject) >
          maxReadAheadSize) {
        break;
      }
    }
    if (!await queue.hasNext) {
      inputStream.setDone();
    } else {
      s.resume();
    }
  });
  return inputStream;
}

/// Information about a failure.
///
/// See [NSError](https://developer.apple.com/documentation/foundation/nserror)
class Error extends _ObjectHolder<ncb.NSError> implements Exception {
  Error._(super.c);

  /// Create an Error from a custom domain.
  factory Error.fromCustomDomain(String domain, int code,
      {String? localizedDescription}) {
    final d = ncb.NSMutableDictionary.alloc(linkedLibs).init();

    if (localizedDescription != null) {
      d.setObject_forKey_(
        localizedDescription.toNSString(linkedLibs),
        ncb.NSString.castFromPointer(
            linkedLibs, linkedLibs.NSLocalizedDescriptionKey),
      );
    }
    final e = ncb.NSError.alloc(linkedLibs)
        .initWithDomain_code_userInfo_(domain.toNSString(linkedLibs), code, d);
    return Error._(e);
  }

  /// The numeric code for the error e.g. -1003 (kCFURLErrorCannotFindHost).
  ///
  /// The interpretation of this code will depend on the domain of the error
  /// which, for URL loading, will usually be
  /// [`kCFErrorDomainCFNetwork`](https://developer.apple.com/documentation/cfnetwork/kcferrordomaincfnetwork).
  ///
  /// See [NSError.code](https://developer.apple.com/documentation/foundation/nserror/1409165-code)
  int get code => _nsObject.code;

  /// The error domain, for example `"NSPOSIXErrorDomain"`.
  ///
  /// See [NSError.domain](https://developer.apple.com/documentation/foundation/nserror/1413924-domain)
  String get domain => _nsObject.domain.toString();

  /// A description of the error in the current locale e.g.
  /// 'A server with the specified hostname could not be found.'
  ///
  /// See [NSError.localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)
  String? get localizedDescription =>
      toStringOrNull(_nsObject.localizedDescription);

  /// An explanation of the reason for the error in the current locale.
  ///
  /// See [NSError.localizedFailureReason](https://developer.apple.com/documentation/foundation/nserror/1412752-localizedfailurereason)
  String? get localizedFailureReason =>
      toStringOrNull(_nsObject.localizedFailureReason);

  /// An explanation of how to fix the error in the current locale.
  ///
  /// See [NSError.localizedRecoverySuggestion](https://developer.apple.com/documentation/foundation/nserror/1407500-localizedrecoverysuggestion)
  String? get localizedRecoverySuggestion =>
      toStringOrNull(_nsObject.localizedRecoverySuggestion);

  @override
  String toString() => '[Error '
      'domain=$domain '
      'code=$code '
      'localizedDescription=$localizedDescription '
      'localizedFailureReason=$localizedFailureReason '
      'localizedRecoverySuggestion=$localizedRecoverySuggestion '
      ']';
}

/// A cache for [URLRequest]s. Used by [URLSessionConfiguration.cache].
///
/// See [NSURLCache](https://developer.apple.com/documentation/foundation/nsurlcache)
class URLCache extends _ObjectHolder<ncb.NSURLCache> {
  URLCache._(super.c);

  /// The default URLCache.
  ///
  /// See [NSURLCache.sharedURLCache](https://developer.apple.com/documentation/foundation/nsurlcache/1413377-sharedurlcache)
  static URLCache? get sharedURLCache {
    final sharedCache = ncb.NSURLCache.getSharedURLCache(linkedLibs);
    return URLCache._(sharedCache);
  }

  /// Create a new [URLCache] with the given memory and disk cache sizes.
  ///
  /// [memoryCapacity] and [diskCapacity] are specified in bytes.
  ///
  /// [directory] is the file system location where the disk cache will be
  /// stored. If `null` then the default directory will be used.
  ///
  /// See [NSURLCache initWithMemoryCapacity:diskCapacity:directoryURL:](https://developer.apple.com/documentation/foundation/nsurlcache/3240612-initwithmemorycapacity)
  factory URLCache.withCapacity(
          {int memoryCapacity = 0, int diskCapacity = 0, Uri? directory}) =>
      URLCache._(ncb.NSURLCache.alloc(linkedLibs)
          .initWithMemoryCapacity_diskCapacity_directoryURL_(memoryCapacity,
              diskCapacity, directory == null ? null : uriToNSURL(directory)));
}

/// Controls the behavior of a URLSession.
///
/// See [NSURLSessionConfiguration](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration)
class URLSessionConfiguration
    extends _ObjectHolder<ncb.NSURLSessionConfiguration> {
  // A configuration created with
  // [`backgroundSessionConfigurationWithIdentifier`](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1407496-backgroundsessionconfigurationwi)
  final bool _isBackground;

  URLSessionConfiguration._(super.c, {required bool isBackground})
      : _isBackground = isBackground;

  /// A configuration suitable for performing HTTP uploads and downloads in
  /// the background.
  ///
  /// See [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1407496-backgroundsessionconfigurationwi)
  factory URLSessionConfiguration.backgroundSession(String identifier) =>
      URLSessionConfiguration._(
          ncb.NSURLSessionConfiguration
              .backgroundSessionConfigurationWithIdentifier_(
                  linkedLibs, identifier.toNSString(linkedLibs)),
          isBackground: true);

  /// A configuration that uses caching and saves cookies and credentials.
  ///
  /// See [NSURLSessionConfiguration defaultSessionConfiguration](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411560-defaultsessionconfiguration)
  factory URLSessionConfiguration.defaultSessionConfiguration() =>
      URLSessionConfiguration._(
          ncb.NSURLSessionConfiguration.castFrom(
              ncb.NSURLSessionConfiguration.getDefaultSessionConfiguration(
                  linkedLibs)),
          isBackground: false);

  /// A session configuration that uses no persistent storage for caches,
  /// cookies, or credentials.
  ///
  /// See [NSURLSessionConfiguration ephemeralSessionConfiguration](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1410529-ephemeralsessionconfiguration)
  factory URLSessionConfiguration.ephemeralSessionConfiguration() =>
      URLSessionConfiguration._(
          ncb.NSURLSessionConfiguration.castFrom(
              ncb.NSURLSessionConfiguration.getEphemeralSessionConfiguration(
                  linkedLibs)),
          isBackground: false);

  /// Whether connections over a cellular network are allowed.
  ///
  /// See [NSURLSessionConfiguration.allowsCellularAccess](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1409406-allowscellularaccess)
  bool get allowsCellularAccess => _nsObject.allowsCellularAccess;
  set allowsCellularAccess(bool value) =>
      _nsObject.allowsCellularAccess = value;

  /// Whether connections are allowed when the user has selected Low Data Mode.
  ///
  /// See [NSURLSessionConfiguration.allowsConstrainedNetworkAccess](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/3235751-allowsconstrainednetworkaccess)
  bool get allowsConstrainedNetworkAccess =>
      _nsObject.allowsConstrainedNetworkAccess;
  set allowsConstrainedNetworkAccess(bool value) =>
      _nsObject.allowsConstrainedNetworkAccess = value;

  /// Whether connections are allowed over expensive networks.
  ///
  /// See [NSURLSessionConfiguration.allowsExpensiveNetworkAccess](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/3235752-allowsexpensivenetworkaccess)
  bool get allowsExpensiveNetworkAccess =>
      _nsObject.allowsExpensiveNetworkAccess;
  set allowsExpensiveNetworkAccess(bool value) =>
      _nsObject.allowsExpensiveNetworkAccess = value;

  /// The [URLCache] used to cache the results of [URLSessionTask]s.
  ///
  /// A value of `nil` indicates that no cache will be used.
  ///
  /// See [NSURLSessionConfiguration.URLCache](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1410148-urlcache)
  URLCache? get cache =>
      _nsObject.URLCache == null ? null : URLCache._(_nsObject.URLCache!);
  set cache(URLCache? cache) => _nsObject.URLCache = cache?._nsObject;

  /// Whether background tasks can be delayed by the system.
  ///
  /// See [NSURLSessionConfiguration.discretionary](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411552-discretionary)
  bool get discretionary => _nsObject.discretionary;
  set discretionary(bool value) => _nsObject.discretionary = value;

  /// Additional headers to send with each request.
  ///
  /// Note that the getter for this field returns a **copy** of the headers.
  ///
  /// See [NSURLSessionConfiguration.HTTPAdditionalHeaders](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411532-httpadditionalheaders)
  Map<String, String>? get httpAdditionalHeaders {
    if (_nsObject.HTTPAdditionalHeaders case var additionalHeaders?) {
      final headers = ncb.NSDictionary.castFrom(additionalHeaders);
      return stringNSDictionaryToMap(headers);
    }
    return null;
  }

  set httpAdditionalHeaders(Map<String, String>? headers) {
    if (headers == null) {
      _nsObject.HTTPAdditionalHeaders = null;
      return;
    }
    final d = ncb.NSMutableDictionary.alloc(linkedLibs).init();
    headers.forEach((key, value) {
      d.setObject_forKey_(
          value.toNSString(linkedLibs), key.toNSString(linkedLibs));
    });
    _nsObject.HTTPAdditionalHeaders = d;
  }

  /// What policy to use when deciding whether to accept cookies.
  ///
  /// See [NSURLSessionConfiguration.HTTPCookieAcceptPolicy](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1408933-httpcookieacceptpolicy).
  HTTPCookieAcceptPolicy get httpCookieAcceptPolicy =>
      HTTPCookieAcceptPolicy.values[_nsObject.HTTPCookieAcceptPolicy];
  set httpCookieAcceptPolicy(HTTPCookieAcceptPolicy value) =>
      _nsObject.HTTPCookieAcceptPolicy = value.index;

  /// The maximum number of connections that a URLSession can have open to the
  /// same host.
  //
  /// See [NSURLSessionConfiguration.HTTPMaximumConnectionsPerHost](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1407597-httpmaximumconnectionsperhost).
  int get httpMaximumConnectionsPerHost =>
      _nsObject.HTTPMaximumConnectionsPerHost;
  set httpMaximumConnectionsPerHost(int value) =>
      _nsObject.HTTPMaximumConnectionsPerHost = value;

  /// Whether requests should include cookies from the cookie store.
  ///
  /// See [NSURLSessionConfiguration.HTTPShouldSetCookies](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411589-httpshouldsetcookies)
  bool get httpShouldSetCookies => _nsObject.HTTPShouldSetCookies;
  set httpShouldSetCookies(bool value) =>
      _nsObject.HTTPShouldSetCookies = value;

  /// Whether to use [HTTP pipelining](https://en.wikipedia.org/wiki/HTTP_pipelining).
  ///
  /// See [NSURLSessionConfiguration.HTTPShouldUsePipelining](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411657-httpshouldusepipelining)
  bool get httpShouldUsePipelining => _nsObject.HTTPShouldUsePipelining;
  set httpShouldUsePipelining(bool value) =>
      _nsObject.HTTPShouldUsePipelining = value;

  /// What type of Multipath TCP connections to use.
  ///
  /// See [NSURLSessionConfiguration.multipathServiceType](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/2875967-multipathservicetype)
  URLSessionMultipathServiceType get multipathServiceType =>
      URLSessionMultipathServiceType.values[_nsObject.multipathServiceType];
  set multipathServiceType(URLSessionMultipathServiceType value) =>
      _nsObject.multipathServiceType = value.index;

  /// Provides in indication to the operating system on what type of requests
  /// are being sent.
  ///
  /// See [NSURLSessionConfiguration.networkServiceType](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411606-networkservicetype).
  URLRequestNetworkService get networkServiceType =>
      URLRequestNetworkService.values[_nsObject.networkServiceType];
  set networkServiceType(URLRequestNetworkService value) =>
      _nsObject.networkServiceType = value.index;

  /// Controls how to deal with response caching.
  ///
  /// See [NSURLSessionConfiguration.requestCachePolicy](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411655-requestcachepolicy)
  URLRequestCachePolicy get requestCachePolicy =>
      URLRequestCachePolicy.values[_nsObject.requestCachePolicy];
  set requestCachePolicy(URLRequestCachePolicy value) =>
      _nsObject.requestCachePolicy = value.index;

  /// Whether the app should be resumed when background tasks complete.
  ///
  /// See [NSURLSessionConfiguration.sessionSendsLaunchEvents](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1617174-sessionsendslaunchevents)
  bool get sessionSendsLaunchEvents => _nsObject.sessionSendsLaunchEvents;
  set sessionSendsLaunchEvents(bool value) =>
      _nsObject.sessionSendsLaunchEvents = value;

  /// Whether connections will be preserved if the app moves to the background.
  ///
  /// See [NSURLSessionConfiguration.shouldUseExtendedBackgroundIdleMode](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1409517-shoulduseextendedbackgroundidlem)
  bool get shouldUseExtendedBackgroundIdleMode =>
      _nsObject.shouldUseExtendedBackgroundIdleMode;
  set shouldUseExtendedBackgroundIdleMode(bool value) =>
      _nsObject.shouldUseExtendedBackgroundIdleMode = value;

  /// The timeout interval if data is not received.
  ///
  /// See [NSURLSessionConfiguration.timeoutIntervalForRequest](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1408259-timeoutintervalforrequest)
  Duration get timeoutIntervalForRequest => Duration(
      microseconds:
          (_nsObject.timeoutIntervalForRequest * Duration.microsecondsPerSecond)
              .round());

  set timeoutIntervalForRequest(Duration interval) {
    _nsObject.timeoutIntervalForRequest =
        interval.inMicroseconds.toDouble() / Duration.microsecondsPerSecond;
  }

  /// Whether tasks should wait for connectivity or fail immediately.
  ///
  /// See [NSURLSessionConfiguration.waitsForConnectivity](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/2908812-waitsforconnectivity)
  bool get waitsForConnectivity => _nsObject.waitsForConnectivity;
  set waitsForConnectivity(bool value) =>
      _nsObject.waitsForConnectivity = value;

  @override
  String toString() => '[URLSessionConfiguration '
      'allowsCellularAccess=$allowsCellularAccess '
      'allowsConstrainedNetworkAccess=$allowsConstrainedNetworkAccess '
      'allowsExpensiveNetworkAccess=$allowsExpensiveNetworkAccess '
      'discretionary=$discretionary '
      'httpAdditionalHeaders=$httpAdditionalHeaders '
      'httpCookieAcceptPolicy=$httpCookieAcceptPolicy '
      'httpShouldSetCookies=$httpShouldSetCookies '
      'httpMaximumConnectionsPerHost=$httpMaximumConnectionsPerHost '
      'httpShouldUsePipelining=$httpShouldUsePipelining '
      'requestCachePolicy=$requestCachePolicy '
      'sessionSendsLaunchEvents=$sessionSendsLaunchEvents '
      'shouldUseExtendedBackgroundIdleMode='
      '$shouldUseExtendedBackgroundIdleMode '
      'timeoutIntervalForRequest=$timeoutIntervalForRequest '
      'waitsForConnectivity=$waitsForConnectivity'
      ']';
}

/// A container for byte data.
///
/// See [NSData](https://developer.apple.com/documentation/foundation/nsdata)
class Data extends _ObjectHolder<ncb.NSData> {
  Data._(super.c);

  /// A new [Data] from an existing one.
  ///
  /// See [NSData dataWithData:](https://developer.apple.com/documentation/foundation/nsdata/1547230-datawithdata)
  factory Data.fromData(Data d) =>
      Data._(ncb.NSData.dataWithData_(linkedLibs, d._nsObject));

  /// A new [Data] object containing the given bytes.
  factory Data.fromList(List<int> l) {
    final buffer = calloc<Uint8>(l.length);
    try {
      buffer.asTypedList(l.length).setAll(0, l);

      final data =
          ncb.NSData.dataWithBytes_length_(linkedLibs, buffer.cast(), l.length);
      return Data._(data);
    } finally {
      calloc.free(buffer);
    }
  }

  /// A new [Data] object containing the given bytes.
  @Deprecated('Use Data.fromList instead')
  factory Data.fromUint8List(Uint8List l) = Data.fromList;

  /// The number of bytes contained in the object.
  ///
  /// See [NSData.length](https://developer.apple.com/documentation/foundation/nsdata/1416769-length)
  int get length => _nsObject.length;

  /// The data contained in the object.
  ///
  /// See [NSData.bytes](https://developer.apple.com/documentation/foundation/nsdata/1410616-bytes)
  Uint8List get bytes {
    final bytes = _nsObject.bytes;
    if (bytes.address == 0) {
      return Uint8List(0);
    } else {
      // `NSData.byte` has the same lifetime as the `NSData` so make a copy to
      // ensure memory safety.
      // TODO(https://github.com/dart-lang/ffigen/issues/375): Remove copy.
      return Uint8List.fromList(bytes.cast<Uint8>().asTypedList(length));
    }
  }

  @override
  String toString() {
    final subrange =
        length == 0 ? Uint8List(0) : bytes.sublist(0, min(length - 1, 20));
    final b = subrange.map((e) => e.toRadixString(16)).join();
    return '[Data length=$length bytes=0x$b...]';
  }
}

/// A container for byte data.
///
/// See [NSMutableData](https://developer.apple.com/documentation/foundation/nsmutabledata)
class MutableData extends Data {
  final ncb.NSMutableData _mutableData;

  MutableData._(ncb.NSMutableData super.c)
      : _mutableData = c,
        super._();

  /// A new empty [MutableData].
  factory MutableData.empty() =>
      MutableData._(ncb.NSMutableData.dataWithCapacity_(linkedLibs, 0)!);

  /// Appends the given data.
  ///
  /// See [NSMutableData appendBytes:length:](https://developer.apple.com/documentation/foundation/nsmutabledata/1407704-appendbytes)
  void appendBytes(List<int> l) {
    final f = calloc<Uint8>(l.length);
    try {
      f.asTypedList(l.length).setAll(0, l);

      _mutableData.appendBytes_length_(f.cast(), l.length);
    } finally {
      calloc.free(f);
    }
  }

  @override
  String toString() {
    final subrange =
        length == 0 ? Uint8List(0) : bytes.sublist(0, min(length - 1, 20));
    final b = subrange.map((e) => e.toRadixString(16)).join();
    return '[MutableData length=$length bytes=0x$b...]';
  }
}

/// The response associated with loading an URL.
///
/// See [NSURLResponse](https://developer.apple.com/documentation/foundation/nsurlresponse)
class URLResponse extends _ObjectHolder<ncb.NSURLResponse> {
  URLResponse._(super.c);

  factory URLResponse._exactURLResponseType(ncb.NSURLResponse response) {
    if (ncb.NSHTTPURLResponse.isInstance(response)) {
      return HTTPURLResponse._(ncb.NSHTTPURLResponse.castFrom(response));
    }
    return URLResponse._(response);
  }

  /// The expected amount of data returned with the response.
  ///
  /// See [NSURLResponse.expectedContentLength](https://developer.apple.com/documentation/foundation/nsurlresponse/1413507-expectedcontentlength)
  int get expectedContentLength => _nsObject.expectedContentLength;

  /// The MIME type of the response.
  ///
  /// See [NSURLResponse.MIMEType](https://developer.apple.com/documentation/foundation/nsurlresponse/1411613-mimetype)
  String? get mimeType => toStringOrNull(_nsObject.MIMEType);

  @override
  String toString() => '[URLResponse '
      'mimeType=$mimeType '
      'expectedContentLength=$expectedContentLength'
      ']';
}

/// The response associated with loading a HTTP URL.
///
/// See [NSHTTPURLResponse](https://developer.apple.com/documentation/foundation/nshttpurlresponse)
class HTTPURLResponse extends URLResponse {
  final ncb.NSHTTPURLResponse _httpUrlResponse;

  HTTPURLResponse._(ncb.NSHTTPURLResponse super.c)
      : _httpUrlResponse = c,
        super._();

  /// The HTTP status code of the response (e.g. 200).
  ///
  /// See [HTTPURLResponse.statusCode](https://developer.apple.com/documentation/foundation/nshttpurlresponse/1409395-statuscode)
  int get statusCode => _httpUrlResponse.statusCode;

  /// The HTTP headers of the response.
  ///
  /// See [HTTPURLResponse.allHeaderFields](https://developer.apple.com/documentation/foundation/nshttpurlresponse/1417930-allheaderfields)
  Map<String, String> get allHeaderFields {
    final headers = ncb.NSDictionary.castFrom(_httpUrlResponse.allHeaderFields);
    return stringNSDictionaryToMap(headers);
  }

  @override
  String toString() => '[HTTPURLResponse '
      'statusCode=$statusCode '
      'mimeType=$mimeType '
      'expectedContentLength=$expectedContentLength'
      ']';
}

/// The possible states of a [URLSessionTask].
///
/// See [NSURLSessionTaskState](https://developer.apple.com/documentation/foundation/nsurlsessiontaskstate)
enum URLSessionTaskState {
  urlSessionTaskStateRunning,
  urlSessionTaskStateSuspended,
  urlSessionTaskStateCanceling,
  urlSessionTaskStateCompleted,
}

/// A WebSocket message.
///
/// See [NSURLSessionWebSocketMessage](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage)
class URLSessionWebSocketMessage
    extends _ObjectHolder<ncb.NSURLSessionWebSocketMessage> {
  URLSessionWebSocketMessage._(super.nsObject);

  /// Create a WebSocket data message.
  ///
  /// See [NSURLSessionWebSocketMessage initWithData:](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage/3181192-initwithdata)
  factory URLSessionWebSocketMessage.fromData(Data d) =>
      URLSessionWebSocketMessage._(
          ncb.NSURLSessionWebSocketMessage.alloc(linkedLibs)
              .initWithData_(d._nsObject));

  /// Create a WebSocket string message.
  ///
  /// See [NSURLSessionWebSocketMessage initWitString:](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage/3181193-initwithstring)
  factory URLSessionWebSocketMessage.fromString(String s) =>
      URLSessionWebSocketMessage._(
          ncb.NSURLSessionWebSocketMessage.alloc(linkedLibs)
              .initWithString_(s.toNSString(linkedLibs)));

  /// The data associated with the WebSocket message.
  ///
  /// Will be `null` if the [URLSessionWebSocketMessage] is a string message.
  ///
  /// See [NSURLSessionWebSocketMessage.data](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage/3181191-data)
  Data? get data => _nsObject.data == null ? null : Data._(_nsObject.data!);

  /// The string associated with the WebSocket message.
  ///
  /// Will be `null` if the [URLSessionWebSocketMessage] is a data message.
  ///
  /// See [NSURLSessionWebSocketMessage.string](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage/3181194-string)
  String? get string => toStringOrNull(_nsObject.string);

  /// The type of the WebSocket message.
  ///
  /// See [NSURLSessionWebSocketMessage.type](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage/3181195-type)
  URLSessionWebSocketMessageType get type =>
      URLSessionWebSocketMessageType.values[_nsObject.type];

  @override
  String toString() =>
      '[URLSessionWebSocketMessage type=$type string=$string data=$data]';
}

/// A task associated with downloading a URI.
///
/// See [NSURLSessionTask](https://developer.apple.com/documentation/foundation/nsurlsessiontask)
class URLSessionTask extends _ObjectHolder<ncb.NSURLSessionTask> {
  URLSessionTask._(super.c);

  /// Cancels the task.
  ///
  /// See [NSURLSessionTask cancel](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411591-cancel)
  void cancel() {
    _nsObject.cancel();
  }

  /// Resumes a suspended task (new tasks start as suspended).
  ///
  /// See [NSURLSessionTask resume](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411121-resume)
  void resume() {
    _nsObject.resume();
  }

  /// Suspends a task (prevents it from transferring data).
  ///
  /// See [NSURLSessionTask suspend](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411565-suspend)
  void suspend() {
    _nsObject.suspend();
  }

  /// The current state of the task.
  ///
  /// See [NSURLSessionTask.state](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1409888-state)
  URLSessionTaskState get state => URLSessionTaskState.values[_nsObject.state];

  /// The relative priority [0, 1] that the host should use to handle the
  /// request.
  ///
  /// See [NSURLSessionTask.priority](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1410569-priority)
  double get priority => _nsObject.priority;

  /// The relative priority [0, 1] that the host should use to handle the
  /// request.
  ///
  /// See [NSURLSessionTask.priority](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1410569-priority)
  set priority(double value) => _nsObject.priority = value;

  /// The request currently being handled by the task.
  ///
  /// May be different from [originalRequest] if the server responds with a
  /// redirect.
  ///
  /// See [NSURLSessionTask.currentRequest](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411649-currentrequest)
  URLRequest? get currentRequest {
    final request = _nsObject.currentRequest;
    if (request == null) {
      return null;
    } else {
      return URLRequest._(request);
    }
  }

  /// The original request associated with the task.
  ///
  /// May be different from [currentRequest] if the server responds with a
  /// redirect.
  ///
  /// See [NSURLSessionTask.originalRequest](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411572-originalrequest)
  URLRequest? get originalRequest {
    final request = _nsObject.originalRequest;
    if (request == null) {
      return null;
    } else {
      return URLRequest._(request);
    }
  }

  /// The server response to the request associated with this task.
  ///
  /// See [NSURLSessionTask.response](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1410586-response)
  URLResponse? get response {
    final nsResponse = _nsObject.response;
    if (nsResponse == null) {
      return null;
    }
    return URLResponse._exactURLResponseType(nsResponse);
  }

  /// An error indicating why the task failed or `null` on success.
  ///
  /// See [NSURLSessionTask.error](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1408145-error)
  Error? get error {
    final error = _nsObject.error;
    if (error == null) {
      return null;
    } else {
      return Error._(error);
    }
  }

  /// The user-assigned description for the task.
  ///
  /// See [NSURLSessionTask.taskDescription](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1409798-taskdescription)
  String get taskDescription => _nsObject.taskDescription.toString();

  /// The user-assigned description for the task.
  ///
  /// See [NSURLSessionTask.taskDescription](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1409798-taskdescription)
  set taskDescription(String value) =>
      _nsObject.taskDescription = value.toNSString(linkedLibs);

  /// A unique ID for the [URLSessionTask] in a [URLSession].
  ///
  /// See [NSURLSessionTask.taskIdentifier](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411231-taskidentifier)
  int get taskIdentifier => _nsObject.taskIdentifier;

  /// The number of content bytes that are expected to be received from the
  /// server.
  ///
  /// See [NSURLSessionTask.countOfBytesReceived](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1410663-countofbytesexpectedtoreceive)
  int get countOfBytesExpectedToReceive =>
      _nsObject.countOfBytesExpectedToReceive;

  /// The number of content bytes that have been received from the server.
  ///
  /// See [NSURLSessionTask.countOfBytesReceived](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411581-countofbytesreceived)
  int get countOfBytesReceived => _nsObject.countOfBytesReceived;

  /// The number of content bytes that the task expects to send to the server.
  ///
  /// See [NSURLSessionTask.countOfBytesExpectedToSend](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411534-countofbytesexpectedtosend)
  int get countOfBytesExpectedToSend => _nsObject.countOfBytesExpectedToSend;

  /// Whether the body of the response should be delivered incrementally or not.
  ///
  /// [NSURLSessionTask.countOfBytesSent](https://developer.apple.com/documentation/foundation/nsurlsessiontask/1410444-countofbytessent)
  int get countOfBytesSent => _nsObject.countOfBytesSent;

  /// Whether the body of the response should be delivered incrementally or not.
  ///
  /// See [NSURLSessionTask.prefersIncrementalDelivery](https://developer.apple.com/documentation/foundation/nsurlsessiontask/3735881-prefersincrementaldelivery)
  bool get prefersIncrementalDelivery => _nsObject.prefersIncrementalDelivery;

  /// Whether the body of the response should be delivered incrementally or not.
  ///
  /// See [NSURLSessionTask.prefersIncrementalDelivery](https://developer.apple.com/documentation/foundation/nsurlsessiontask/3735881-prefersincrementaldelivery)
  set prefersIncrementalDelivery(bool value) =>
      _nsObject.prefersIncrementalDelivery = value;

  String _toStringHelper(String className) => '[$className '
      'taskDescription=$taskDescription '
      'taskIdentifier=$taskIdentifier '
      'countOfBytesExpectedToReceive=$countOfBytesExpectedToReceive '
      'countOfBytesReceived=$countOfBytesReceived '
      'countOfBytesExpectedToSend=$countOfBytesExpectedToSend '
      'countOfBytesSent=$countOfBytesSent '
      'priority=$priority '
      'state=$state '
      'prefersIncrementalDelivery=$prefersIncrementalDelivery'
      ']';

  @override
  String toString() => _toStringHelper('URLSessionTask');
}

/// A task associated with downloading a URI to a file.
///
/// See [NSURLSessionDownloadTask](https://developer.apple.com/documentation/foundation/nsurlsessiondownloadtask)
class URLSessionDownloadTask extends URLSessionTask {
  URLSessionDownloadTask._(ncb.NSURLSessionDownloadTask super.c) : super._();

  @override
  String toString() => _toStringHelper('URLSessionDownloadTask');
}

/// A task associated with a WebSocket connection.
///
/// See [NSURLSessionWebSocketTask](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask)
class URLSessionWebSocketTask extends URLSessionTask {
  final ncb.NSURLSessionWebSocketTask _urlSessionWebSocketTask;

  URLSessionWebSocketTask._(ncb.NSURLSessionWebSocketTask super.c)
      : _urlSessionWebSocketTask = c,
        super._();

  /// The close code set when the WebSocket connection is closed.
  ///
  /// See [NSURLSessionWebSocketTask.closeCode](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask/3181201-closecode)
  int get closeCode => _urlSessionWebSocketTask.closeCode;

  /// The close reason set when the WebSocket connection is closed.
  /// If there is no close reason available this property will be null.
  ///
  /// See [NSURLSessionWebSocketTask.closeReason](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask/3181202-closereason)
  Data? get closeReason {
    final reason = _urlSessionWebSocketTask.closeReason;
    if (reason == null) {
      return null;
    } else {
      return Data._(reason);
    }
  }

  /// Sends a single WebSocket message.
  ///
  /// The returned future will complete successfully when the message is sent
  /// and with an [Error] on failure.
  ///
  /// See [NSURLSessionWebSocketTask.sendMessage:completionHandler:](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask/3181205-sendmessage)
  Future<void> sendMessage(URLSessionWebSocketMessage message) async {
    final completer = Completer<void>();
    final completionPort = ReceivePort();
    completionPort.listen((message) {
      final ep = Pointer<ncb.ObjCObject>.fromAddress(message as int);
      if (ep.address == 0) {
        completer.complete();
      } else {
        final error = Error._(ncb.NSError.castFromPointer(linkedLibs, ep,
            retain: false, release: true));
        completer.completeError(error);
      }
      completionPort.close();
    });

    helperLibs.CUPHTTPSendMessage(_urlSessionWebSocketTask, message._nsObject,
        completionPort.sendPort.nativePort);
    await completer.future;
  }

  /// Receives a single WebSocket message.
  ///
  /// Throws an [Error] on failure.
  ///
  /// See [NSURLSessionWebSocketTask.receiveMessageWithCompletionHandler:](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask/3181204-receivemessagewithcompletionhand)
  Future<URLSessionWebSocketMessage> receiveMessage() async {
    final completer = Completer<URLSessionWebSocketMessage>();
    final completionPort = ReceivePort();
    completionPort.listen((d) {
      final messageAndError = d as List;

      final mp = Pointer<ncb.ObjCObject>.fromAddress(messageAndError[0] as int);
      final ep = Pointer<ncb.ObjCObject>.fromAddress(messageAndError[1] as int);

      final message = mp.address == 0
          ? null
          : URLSessionWebSocketMessage._(
              ncb.NSURLSessionWebSocketMessage.castFromPointer(linkedLibs, mp,
                  retain: false, release: true));
      final error = ep.address == 0
          ? null
          : Error._(ncb.NSError.castFromPointer(linkedLibs, ep,
              retain: false, release: true));

      if (error != null) {
        completer.completeError(error);
      } else {
        completer.complete(message!);
      }
      completionPort.close();
    });

    helperLibs.CUPHTTPReceiveMessage(
        _urlSessionWebSocketTask, completionPort.sendPort.nativePort);
    return completer.future;
  }

  /// Sends close frame with the given code and optional reason.
  ///
  /// See [NSURLSessionWebSocketTask.cancelWithCloseCode:reason:](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask/3181200-cancelwithclosecode)
  void cancelWithCloseCode(int closeCode, Data? reason) {
    _urlSessionWebSocketTask.cancelWithCloseCode_reason_(
        closeCode, reason?._nsObject);
  }

  @override
  String toString() => _toStringHelper('NSURLSessionWebSocketTask');
}

/// A request to load a URL.
///
/// See [NSURLRequest](https://developer.apple.com/documentation/foundation/nsurlrequest)
class URLRequest extends _ObjectHolder<ncb.NSURLRequest> {
  URLRequest._(super.c);

  /// Creates a request for a URL.
  ///
  /// See [NSURLRequest.requestWithURL:](https://developer.apple.com/documentation/foundation/nsurlrequest/1528603-requestwithurl)
  factory URLRequest.fromUrl(Uri uri) => URLRequest._(
      ncb.NSURLRequest.requestWithURL_(linkedLibs, uriToNSURL(uri)));

  /// Returns all of the HTTP headers for the request.
  ///
  /// See [NSURLRequest.allHTTPHeaderFields](https://developer.apple.com/documentation/foundation/nsurlrequest/1418477-allhttpheaderfields)
  Map<String, String>? get allHttpHeaderFields {
    if (_nsObject.allHTTPHeaderFields == null) {
      return null;
    } else {
      final headers = ncb.NSDictionary.castFrom(_nsObject.allHTTPHeaderFields!);
      return stringNSDictionaryToMap(headers);
    }
  }

  /// Controls how to deal with caching for the request.
  ///
  /// See [NSURLSession.cachePolicy](https://developer.apple.com/documentation/foundation/nsurlrequest/1407944-cachepolicy)
  URLRequestCachePolicy get cachePolicy =>
      URLRequestCachePolicy.values[_nsObject.cachePolicy];

  /// The body of the request.
  ///
  /// See [NSURLRequest.HTTPBody](https://developer.apple.com/documentation/foundation/nsurlrequest/1411317-httpbody)
  Data? get httpBody {
    final body = _nsObject.HTTPBody;
    if (body == null) {
      return null;
    }
    return Data._(ncb.NSData.castFrom(body));
  }

  /// The HTTP request method (e.g. 'GET').
  ///
  /// See [NSURLRequest.HTTPMethod](https://developer.apple.com/documentation/foundation/nsurlrequest/1413030-httpmethod)
  ///
  /// NOTE: The documentation for `NSURLRequest.HTTPMethod` says that the
  /// property is nullable but, in practice, assigning it to null will produce
  /// an error.
  String get httpMethod => _nsObject.HTTPMethod!.toString();

  /// The timeout interval during the connection attempt.
  ///
  /// See [NSURLSession.timeoutInterval](https://developer.apple.com/documentation/foundation/nsurlrequest/1418229-timeoutinterval)
  Duration get timeoutInterval => Duration(
      microseconds:
          (_nsObject.timeoutInterval * Duration.microsecondsPerSecond).round());

  /// The requested URL.
  ///
  /// See [URLRequest.URL](https://developer.apple.com/documentation/foundation/nsurlrequest/1408996-url)
  Uri? get url {
    final nsUrl = _nsObject.URL;
    if (nsUrl == null) {
      return null;
    }
    return Uri.parse(nsUrl.absoluteString!.toString());
  }

  @override
  String toString() => '[URLRequest '
      'allHttpHeaderFields=$allHttpHeaderFields '
      'cachePolicy=$cachePolicy '
      'httpBody=$httpBody '
      'httpMethod=$httpMethod '
      'timeoutInterval=$timeoutInterval '
      'url=$url '
      ']';
}

/// A mutable request to load a URL.
///
/// See [NSMutableURLRequest](https://developer.apple.com/documentation/foundation/nsmutableurlrequest)
class MutableURLRequest extends URLRequest {
  final ncb.NSMutableURLRequest _mutableUrlRequest;

  MutableURLRequest._(ncb.NSMutableURLRequest super.c)
      : _mutableUrlRequest = c,
        super._();

  /// Creates a request for a URL.
  ///
  /// See [NSMutableURLRequest.requestWithURL:](https://developer.apple.com/documentation/foundation/nsmutableurlrequest/1414617-allhttpheaderfields)
  factory MutableURLRequest.fromUrl(Uri uri) {
    final url = ncb.NSURL
        .URLWithString_(linkedLibs, uri.toString().toNSString(linkedLibs))!;
    return MutableURLRequest._(
        ncb.NSMutableURLRequest.requestWithURL_(linkedLibs, url));
  }

  set cachePolicy(URLRequestCachePolicy value) =>
      _mutableUrlRequest.cachePolicy = value.index;

  set httpBody(Data? data) {
    _mutableUrlRequest.HTTPBody = data?._nsObject;
  }

  /// Sets the body of the request to the given [Stream].
  ///
  /// See [NSMutableURLRequest.HTTPBodyStream](https://developer.apple.com/documentation/foundation/nsurlrequest/1407341-httpbodystream).
  set httpBodyStream(Stream<List<int>> stream) {
    _mutableUrlRequest.HTTPBodyStream = _streamToNSInputStream(stream);
  }

  set httpMethod(String method) {
    _mutableUrlRequest.HTTPMethod = method.toNSString(linkedLibs);
  }

  set timeoutInterval(Duration interval) {
    _mutableUrlRequest.timeoutInterval =
        interval.inMicroseconds.toDouble() / Duration.microsecondsPerSecond;
  }

  /// Set the value of a header field.
  ///
  /// See [NSMutableURLRequest setValue:forHTTPHeaderField:](https://developer.apple.com/documentation/foundation/nsmutableurlrequest/1408793-setvalue)
  void setValueForHttpHeaderField(String value, String field) {
    _mutableUrlRequest.setValue_forHTTPHeaderField_(
        field.toNSString(linkedLibs), value.toNSString(linkedLibs));
  }

  @override
  String toString() => '[MutableURLRequest '
      'allHttpHeaderFields=$allHttpHeaderFields '
      'cachePolicy=$cachePolicy '
      'httpBody=$httpBody '
      'httpMethod=$httpMethod '
      'timeoutInterval=$timeoutInterval '
      'url=$url '
      ']';
}

/// Setup delegation for the given [task] to the given methods.
///
/// Specifically, this causes the Objective-C-implemented delegate installed
/// with
/// [sessionWithConfiguration:delegate:delegateQueue:](https://developer.apple.com/documentation/foundation/nsurlsession/1411597-sessionwithconfiguration)
/// to send a [ncb.CUPHTTPForwardedDelegate] object to a send port, which is
/// then processed by [_setupDelegation] and forwarded to the given methods.
void _setupDelegation(
  ncb.CUPHTTPClientDelegate delegate,
  URLSession session,
  URLSessionTask task, {
  URLRequest? Function(URLSession session, URLSessionTask task,
          HTTPURLResponse response, URLRequest newRequest)?
      onRedirect,
  URLSessionResponseDisposition Function(
          URLSession session, URLSessionTask task, URLResponse response)?
      onResponse,
  void Function(URLSession session, URLSessionTask task, Data error)? onData,
  void Function(URLSession session, URLSessionDownloadTask task, Uri uri)?
      onFinishedDownloading,
  void Function(URLSession session, URLSessionTask task, Error? error)?
      onComplete,
  void Function(
          URLSession session, URLSessionWebSocketTask task, String? protocol)?
      onWebSocketTaskOpened,
  void Function(URLSession session, URLSessionWebSocketTask task, int closeCode,
          Data? reason)?
      onWebSocketTaskClosed,
}) {
  final responsePort = ReceivePort();
  responsePort.listen((d) {
    final message = d as List;
    final messageType = message[0];
    final dp = Pointer<ncb.ObjCObject>.fromAddress(message[1] as int);

    final forwardedDelegate = ncb.CUPHTTPForwardedDelegate.castFromPointer(
        helperLibs, dp,
        retain: true, release: true);

    switch (messageType) {
      case ncb.MessageType.RedirectMessage:
        final forwardedRedirect =
            ncb.CUPHTTPForwardedRedirect.castFrom(forwardedDelegate);
        URLRequest? redirectRequest;

        try {
          final request = URLRequest._(
              ncb.NSURLRequest.castFrom(forwardedRedirect.request));

          if (onRedirect == null) {
            redirectRequest = request;
            break;
          }
          try {
            final response = HTTPURLResponse._(
                ncb.NSHTTPURLResponse.castFrom(forwardedRedirect.response));
            redirectRequest = onRedirect(session, task, response, request);
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          forwardedRedirect.finishWithRequest_(redirectRequest?._nsObject);
        }
        break;
      case ncb.MessageType.ResponseMessage:
        final forwardedResponse =
            ncb.CUPHTTPForwardedResponse.castFrom(forwardedDelegate);
        var disposition =
            URLSessionResponseDisposition.urlSessionResponseCancel;

        try {
          if (onResponse == null) {
            disposition = URLSessionResponseDisposition.urlSessionResponseAllow;
            break;
          }
          final response =
              URLResponse._exactURLResponseType(forwardedResponse.response);

          try {
            disposition = onResponse(session, task, response);
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          forwardedResponse.finishWithDisposition_(disposition.index);
        }
        break;
      case ncb.MessageType.DataMessage:
        final forwardedData =
            ncb.CUPHTTPForwardedData.castFrom(forwardedDelegate);

        try {
          if (onData == null) {
            break;
          }
          try {
            onData(
                session, task, Data._(ncb.NSData.castFrom(forwardedData.data)));
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          forwardedData.finish();
        }
        break;
      case ncb.MessageType.FinishedDownloading:
        final finishedDownloading =
            ncb.CUPHTTPForwardedFinishedDownloading.castFrom(forwardedDelegate);
        try {
          if (onFinishedDownloading == null) {
            break;
          }
          try {
            onFinishedDownloading(
                session,
                task as URLSessionDownloadTask,
                Uri.parse(
                    finishedDownloading.location.absoluteString!.toString()));
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          finishedDownloading.finish();
        }
        break;
      case ncb.MessageType.CompletedMessage:
        final forwardedComplete =
            ncb.CUPHTTPForwardedComplete.castFrom(forwardedDelegate);

        try {
          if (onComplete == null) {
            break;
          }
          Error? error;
          if (forwardedComplete.error != null) {
            error = Error._(ncb.NSError.castFrom(forwardedComplete.error!));
          }
          try {
            onComplete(session, task, error);
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          forwardedComplete.finish();
          responsePort.close();
        }
        break;
      case ncb.MessageType.WebSocketOpened:
        final webSocketOpened =
            ncb.CUPHTTPForwardedWebSocketOpened.castFrom(forwardedDelegate);

        try {
          if (onWebSocketTaskOpened == null) {
            break;
          }
          try {
            onWebSocketTaskOpened(session, task as URLSessionWebSocketTask,
                webSocketOpened.protocol?.toString());
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          webSocketOpened.finish();
        }
        break;
      case ncb.MessageType.WebSocketClosed:
        final webSocketClosed =
            ncb.CUPHTTPForwardedWebSocketClosed.castFrom(forwardedDelegate);

        try {
          if (onWebSocketTaskClosed == null) {
            break;
          }
          try {
            onWebSocketTaskClosed(
                session,
                task as URLSessionWebSocketTask,
                webSocketClosed.closeCode,
                webSocketClosed.reason == null
                    ? null
                    : Data._(webSocketClosed.reason!));
          } catch (e) {
            // TODO(https://github.com/dart-lang/ffigen/issues/386): Package
            // this exception as an `Error` and call the completion function
            // with it.
          }
        } finally {
          webSocketClosed.finish();
        }
        break;
    }
  });
  final config = ncb.CUPHTTPTaskConfiguration.castFrom(
      ncb.CUPHTTPTaskConfiguration.alloc(helperLibs)
          .initWithPort_(responsePort.sendPort.nativePort));

  delegate.registerTask_withConfiguration_(task._nsObject, config);
}

/// A client that can make network requests to a server.
///
/// See [NSURLSession](https://developer.apple.com/documentation/foundation/nsurlsession)
class URLSession extends _ObjectHolder<ncb.NSURLSession> {
  // Provide our own native delegate to `NSURLSession` because delegates can be
  // called on arbitrary threads and Dart code cannot be.
  static final _delegate = ncb.CUPHTTPClientDelegate.new1(helperLibs);
  // Indicates if the session is a background session. Copied from the
  // [URLSessionConfiguration._isBackground] associated with this [URLSession].
  final bool _isBackground;

  final URLRequest? Function(URLSession session, URLSessionTask task,
      HTTPURLResponse response, URLRequest newRequest)? _onRedirect;
  final URLSessionResponseDisposition Function(
          URLSession session, URLSessionTask task, URLResponse response)?
      _onResponse;
  final void Function(URLSession session, URLSessionTask task, Data error)?
      _onData;
  final void Function(URLSession session, URLSessionTask task, Error? error)?
      _onComplete;
  final void Function(URLSession session, URLSessionDownloadTask task, Uri uri)?
      _onFinishedDownloading;
  final void Function(
          URLSession session, URLSessionWebSocketTask task, String? protocol)?
      _onWebSocketTaskOpened;
  final void Function(URLSession session, URLSessionWebSocketTask task,
      int closeCode, Data? reason)? _onWebSocketTaskClosed;

  URLSession._(
    super.c, {
    required bool isBackground,
    URLRequest? Function(URLSession session, URLSessionTask task,
            HTTPURLResponse response, URLRequest newRequest)?
        onRedirect,
    URLSessionResponseDisposition Function(
            URLSession session, URLSessionTask task, URLResponse response)?
        onResponse,
    void Function(URLSession session, URLSessionTask task, Data error)? onData,
    void Function(URLSession session, URLSessionDownloadTask task, Uri uri)?
        onFinishedDownloading,
    void Function(URLSession session, URLSessionTask task, Error? error)?
        onComplete,
    void Function(
            URLSession session, URLSessionWebSocketTask task, String? protocol)?
        onWebSocketTaskOpened,
    void Function(URLSession session, URLSessionWebSocketTask task,
            int closeCode, Data? reason)?
        onWebSocketTaskClosed,
  })  : _isBackground = isBackground,
        _onRedirect = onRedirect,
        _onResponse = onResponse,
        _onData = onData,
        _onFinishedDownloading = onFinishedDownloading,
        _onComplete = onComplete,
        _onWebSocketTaskOpened = onWebSocketTaskOpened,
        _onWebSocketTaskClosed = onWebSocketTaskClosed;

  /// A client with reasonable default behavior.
  ///
  /// See [NSURLSession.sharedSession](https://developer.apple.com/documentation/foundation/nsurlsession/1409000-sharedsession)
  factory URLSession.sharedSession() => URLSession.sessionWithConfiguration(
      URLSessionConfiguration.defaultSessionConfiguration());

  /// A client with a given configuration.
  ///
  /// If [onRedirect] is set then it will be called whenever a HTTP
  /// request returns a redirect response (e.g. 302). The `response` parameter
  /// contains the response from the server. The `newRequest` parameter contains
  /// a follow-up request that would honor the server's redirect. If the return
  /// value of this function is `null` then the redirect will not occur.
  /// Otherwise, the returned [URLRequest] (usually `newRequest`) will be
  /// executed. [onRedirect] will not be called for background sessions, which
  /// automatically follow redirects. See
  /// [URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:](https://developer.apple.com/documentation/foundation/nsurlsessiontaskdelegate/1411626-urlsession)
  ///
  /// If [onResponse] is set then it will be called whenever a valid response
  /// is received. The returned [URLSessionResponseDisposition] will decide
  /// how the content of the response is processed. See
  /// [URLSession:dataTask:didReceiveResponse:completionHandler:](https://developer.apple.com/documentation/foundation/nsurlsessiondatadelegate/1410027-urlsession)
  ///
  /// If [onData] is set then it will be called whenever response data is
  /// received. If the amount of received data is large, then it may be
  /// called more than once. See
  /// [URLSession:dataTask:didReceiveData:](https://developer.apple.com/documentation/foundation/nsurlsessiondatadelegate/1411528-urlsession)
  ///
  /// If [onFinishedDownloading] is set then it will be called whenever a
  /// [URLSessionDownloadTask] has finished downloading.
  ///
  /// If [onComplete] is set then it will be called when a task completes. If
  /// `error` is `null` then the request completed successfully. See
  /// [URLSession:task:didCompleteWithError:](https://developer.apple.com/documentation/foundation/nsurlsessiontaskdelegate/1411610-urlsession)
  ///
  /// See [sessionWithConfiguration:delegate:delegateQueue:](https://developer.apple.com/documentation/foundation/nsurlsession/1411597-sessionwithconfiguration)
  ///
  /// If [onWebSocketTaskOpened] is set then it will be called when a
  /// [URLSessionWebSocketTask] successfully negotiated the handshake with the
  /// server.
  ///
  /// If [onWebSocketTaskClosed] is set then it will be called if a
  /// [URLSessionWebSocketTask] receives a close control frame from the server.
  /// NOTE: A [URLSessionWebSocketTask.receiveMessage] must be in flight for
  /// [onWebSocketTaskClosed] to be called.
  factory URLSession.sessionWithConfiguration(
    URLSessionConfiguration config, {
    URLRequest? Function(URLSession session, URLSessionTask task,
            HTTPURLResponse response, URLRequest newRequest)?
        onRedirect,
    URLSessionResponseDisposition Function(
            URLSession session, URLSessionTask task, URLResponse response)?
        onResponse,
    void Function(URLSession session, URLSessionTask task, Data error)? onData,
    void Function(URLSession session, URLSessionDownloadTask task, Uri uri)?
        onFinishedDownloading,
    void Function(URLSession session, URLSessionTask task, Error? error)?
        onComplete,
    void Function(
            URLSession session, URLSessionWebSocketTask task, String? protocol)?
        onWebSocketTaskOpened,
    void Function(URLSession session, URLSessionWebSocketTask task,
            int? closeCode, Data? reason)?
        onWebSocketTaskClosed,
  }) {
    // Avoid the complexity of simultaneous or out-of-order delegate callbacks
    // by only allowing callbacks to execute sequentially.
    // See https://developer.apple.com/forums/thread/47252
    // NOTE: this is likely to reduce throughput when there are multiple
    // requests in flight because each call to a delegate waits on a lock
    // that is unlocked by Dart code.
    final queue = ncb.NSOperationQueue.new1(linkedLibs)
      ..maxConcurrentOperationCount = 1
      ..name =
          'cupertino_http.NSURLSessionDelegateQueue'.toNSString(linkedLibs);

    return URLSession._(
        ncb.NSURLSession.sessionWithConfiguration_delegate_delegateQueue_(
            linkedLibs, config._nsObject, _delegate, queue),
        isBackground: config._isBackground,
        onRedirect: onRedirect,
        onResponse: onResponse,
        onData: onData,
        onFinishedDownloading: onFinishedDownloading,
        onComplete: onComplete,
        onWebSocketTaskOpened: onWebSocketTaskOpened,
        onWebSocketTaskClosed: onWebSocketTaskClosed);
  }

  /// A **copy** of the configuration for this session.
  ///
  /// See [NSURLSession.configuration](https://developer.apple.com/documentation/foundation/nsurlsession/1411477-configuration)
  URLSessionConfiguration get configuration => URLSessionConfiguration._(
      ncb.NSURLSessionConfiguration.castFrom(_nsObject.configuration),
      isBackground: _isBackground);

  /// A description of the session that may be useful for debugging.
  ///
  /// See [NSURLSession.sessionDescription](https://developer.apple.com/documentation/foundation/nsurlsession/1408277-sessiondescription)
  String? get sessionDescription =>
      toStringOrNull(_nsObject.sessionDescription);
  set sessionDescription(String? value) =>
      _nsObject.sessionDescription = value?.toNSString(linkedLibs);

  /// Create a [URLSessionTask] that accesses a server URL.
  ///
  /// See [NSURLSession dataTaskWithRequest:](https://developer.apple.com/documentation/foundation/nsurlsession/1410592-datataskwithrequest)
  URLSessionTask dataTaskWithRequest(URLRequest request) {
    final task =
        URLSessionTask._(_nsObject.dataTaskWithRequest_(request._nsObject));
    _setupDelegation(_delegate, this, task,
        onComplete: _onComplete,
        onData: _onData,
        onFinishedDownloading: _onFinishedDownloading,
        onRedirect: _onRedirect,
        onResponse: _onResponse);
    return task;
  }

  /// Creates a [URLSessionTask] that accesses a server URL and calls
  /// [completion] when done.
  ///
  /// See [NSURLSession dataTaskWithRequest:completionHandler:](https://developer.apple.com/documentation/foundation/nsurlsession/1407613-datataskwithrequest)
  URLSessionTask dataTaskWithCompletionHandler(
      URLRequest request,
      void Function(Data? data, HTTPURLResponse? response, Error? error)
          completion) {
    // This method cannot be implemented by simply calling
    // `dataTaskWithRequest:completionHandler:` because the completion handler
    // will invoke the Dart callback on an arbitrary thread and Dart code
    // cannot be run that way
    // (see https://github.com/dart-lang/sdk/issues/37022).
    //
    // Instead, we use `dataTaskWithRequest:` and:
    // 1. create a port to receive information about the request.
    // 2. use a delegate to send information about the task to the port
    // 3. call the user-provided completion function when we receive the
    //    `CompletedMessage` message type.
    final task =
        URLSessionTask._(_nsObject.dataTaskWithRequest_(request._nsObject));

    HTTPURLResponse? finalResponse;
    MutableData? allData;

    _setupDelegation(_delegate, this, task, onRedirect: _onRedirect, onResponse:
        (URLSession session, URLSessionTask task, URLResponse response) {
      finalResponse =
          HTTPURLResponse._(ncb.NSHTTPURLResponse.castFrom(response._nsObject));
      return URLSessionResponseDisposition.urlSessionResponseAllow;
    }, onData: (URLSession session, URLSessionTask task, Data data) {
      allData ??= MutableData.empty();
      allData!.appendBytes(data.bytes);
    }, onComplete: (URLSession session, URLSessionTask task, Error? error) {
      completion(allData == null ? null : Data.fromData(allData!),
          finalResponse, error);
    });

    return URLSessionTask._(task._nsObject);
  }

  /// Creates a [URLSessionDownloadTask] that downloads the data from a server
  /// URL.
  ///
  /// Provide a `onFinishedDownloading` handler in the [URLSession] factory to
  /// receive notifications when the data has completed downloaded.
  ///
  /// See [NSURLSession downloadTaskWithRequest:](https://developer.apple.com/documentation/foundation/nsurlsession/1411481-downloadtaskwithrequest)
  URLSessionDownloadTask downloadTaskWithRequest(URLRequest request) {
    final task = URLSessionDownloadTask._(
        _nsObject.downloadTaskWithRequest_(request._nsObject));
    _setupDelegation(_delegate, this, task,
        onComplete: _onComplete,
        onData: _onData,
        onFinishedDownloading: _onFinishedDownloading,
        onRedirect: _onRedirect,
        onResponse: _onResponse);
    return task;
  }

  /// Creates a [URLSessionWebSocketTask] that represents a connection to a
  /// WebSocket endpoint.
  ///
  /// To add custom protocols, add a "Sec-WebSocket-Protocol" header with a list
  /// of protocols to [request].
  ///
  /// See [NSURLSession webSocketTaskWithRequest:](https://developer.apple.com/documentation/foundation/nsurlsession/3235750-websockettaskwithrequest)
  URLSessionWebSocketTask webSocketTaskWithRequest(URLRequest request) {
    if (_isBackground) {
      throw UnsupportedError(
          'WebSocket tasks are not supported in background sessions');
    }
    final task = URLSessionWebSocketTask._(
        _nsObject.webSocketTaskWithRequest_(request._nsObject));
    _setupDelegation(_delegate, this, task,
        onComplete: _onComplete,
        onData: _onData,
        onFinishedDownloading: _onFinishedDownloading,
        onRedirect: _onRedirect,
        onResponse: _onResponse,
        onWebSocketTaskOpened: _onWebSocketTaskOpened,
        onWebSocketTaskClosed: _onWebSocketTaskClosed);
    return task;
  }

  /// Creates a [URLSessionWebSocketTask] that represents a connection to a
  /// WebSocket endpoint.
  ///
  /// See [NSURLSession webSocketTaskWithURL:protocols:](https://developer.apple.com/documentation/foundation/nsurlsession/3181172-websockettaskwithurl)
  URLSessionWebSocketTask webSocketTaskWithURL(Uri uri,
      {Iterable<String>? protocols}) {
    if (_isBackground) {
      throw UnsupportedError(
          'WebSocket tasks are not supported in background sessions');
    }

    final URLSessionWebSocketTask task;
    if (protocols == null) {
      task = URLSessionWebSocketTask._(
          _nsObject.webSocketTaskWithURL_(uriToNSURL(uri)));
    } else {
      task = URLSessionWebSocketTask._(
          _nsObject.webSocketTaskWithURL_protocols_(
              uriToNSURL(uri), stringIterableToNSArray(protocols)));
    }
    _setupDelegation(_delegate, this, task,
        onComplete: _onComplete,
        onData: _onData,
        onFinishedDownloading: _onFinishedDownloading,
        onRedirect: _onRedirect,
        onResponse: _onResponse,
        onWebSocketTaskOpened: _onWebSocketTaskOpened,
        onWebSocketTaskClosed: _onWebSocketTaskClosed);
    return task;
  }

  /// Free resources related to this session after the last task completes.
  /// Returns immediately.
  ///
  /// See [NSURLSession finishTasksAndInvalidate](https://developer.apple.com/documentation/foundation/nsurlsession/1407428-finishtasksandinvalidate)
  void finishTasksAndInvalidate() {
    _nsObject.finishTasksAndInvalidate();
  }
}
