// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#104231)
// ignore: unnecessary_import
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter_wkwebview/src/common/weak_reference_utils.dart';

import '../common/instance_manager.dart';
import 'foundation_api_impls.dart';

/// The values that can be returned in a change map.
///
/// Wraps [NSKeyValueObservingOptions](https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc).
enum NSKeyValueObservingOptions {
  /// Indicates that the change map should provide the new attribute value, if applicable.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptionnew?language=objc.
  newValue,

  /// Indicates that the change map should contain the old attribute value, if applicable.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptionold?language=objc.
  oldValue,

  /// Indicates a notification should be sent to the observer immediately.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptioninitial?language=objc.
  initialValue,

  /// Whether separate notifications should be sent to the observer before and after each change.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions/nskeyvalueobservingoptionprior?language=objc.
  priorNotification,
}

/// The kinds of changes that can be observed.
///
/// Wraps [NSKeyValueChange](https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc).
enum NSKeyValueChange {
  /// Indicates that the value of the observed key path was set to a new value.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangesetting?language=objc.
  setting,

  /// Indicates that an object has been inserted into the to-many relationship that is being observed.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangeinsertion?language=objc.
  insertion,

  /// Indicates that an object has been removed from the to-many relationship that is being observed.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangeremoval?language=objc.
  removal,

  /// Indicates that an object has been replaced in the to-many relationship that is being observed.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechange/nskeyvaluechangereplacement?language=objc.
  replacement,
}

/// The keys that can appear in the change map.
///
/// Wraps [NSKeyValueChangeKey](https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc).
enum NSKeyValueChangeKey {
  /// Indicates changes made in a collection.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechangeindexeskey?language=objc.
  indexes,

  /// Indicates what sort of change has occurred.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechangekindkey?language=objc.
  kind,

  /// Indicates the new value for the attribute.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechangenewkey?language=objc.
  newValue,

  /// Indicates a notification is sent prior to a change.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechangenotificationispriorkey?language=objc.
  notificationIsPrior,

  /// Indicates the value of this key is the value before the attribute was changed.
  ///
  /// See https://developer.apple.com/documentation/foundation/nskeyvaluechangeoldkey?language=objc.
  oldValue,
}

/// The supported keys in a cookie attributes dictionary.
///
/// Wraps [NSHTTPCookiePropertyKey](https://developer.apple.com/documentation/foundation/nshttpcookiepropertykey).
enum NSHttpCookiePropertyKey {
  /// A String object containing the comment for the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiecomment.
  comment,

  /// A String object containing the comment URL for the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiecommenturl.
  commentUrl,

  /// A String object stating whether the cookie should be discarded at the end of the session.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiediscard.
  discard,

  /// A String object specifying the expiration date for the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiedomain.
  domain,

  /// A String object specifying the expiration date for the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookieexpires.
  expires,

  /// A String object containing an integer value stating how long in seconds the cookie should be kept, at most.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiemaximumage.
  maximumAge,

  /// A String object containing the name of the cookie (required).
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiename.
  name,

  /// A String object containing the URL that set this cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookieoriginurl.
  originUrl,

  /// A String object containing the path for the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiepath.
  path,

  /// A String object containing comma-separated integer values specifying the ports for the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookieport.
  port,

  /// A String indicating the same-site policy for the cookie.
  ///
  /// This is only supported on iOS version 13+. This value will be ignored on
  /// versions < 13.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiesamesitepolicy.
  sameSitePolicy,

  /// A String object indicating that the cookie should be transmitted only over secure channels.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookiesecure.
  secure,

  /// A String object containing the value of the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookievalue.
  value,

  /// A String object that specifies the version of the cookie.
  ///
  /// See https://developer.apple.com/documentation/foundation/nshttpcookieversion.
  version,
}

/// A URL load request that is independent of protocol or URL scheme.
///
/// Wraps [NSUrlRequest](https://developer.apple.com/documentation/foundation/nsurlrequest?language=objc).
@immutable
class NSUrlRequest {
  /// Constructs an [NSUrlRequest].
  const NSUrlRequest({
    required this.url,
    this.httpMethod,
    this.httpBody,
    this.allHttpHeaderFields = const <String, String>{},
  });

  /// The URL being requested.
  final String url;

  /// The HTTP request method.
  ///
  /// The default HTTP method is “GET”.
  final String? httpMethod;

  /// Data sent as the message body of a request, as in an HTTP POST request.
  final Uint8List? httpBody;

  /// All of the HTTP header fields for a request.
  final Map<String, String> allHttpHeaderFields;
}

/// Information about an error condition.
///
/// Wraps [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc).
@immutable
class NSError {
  /// Constructs an [NSError].
  const NSError({
    required this.code,
    required this.domain,
    required this.localizedDescription,
  });

  /// The error code.
  ///
  /// Note that errors are domain-specific.
  final int code;

  /// A string containing the error domain.
  final String domain;

  /// A string containing the localized description of the error.
  final String localizedDescription;
}

/// A representation of an HTTP cookie.
///
/// Wraps [NSHTTPCookie](https://developer.apple.com/documentation/foundation/nshttpcookie).
@immutable
class NSHttpCookie {
  /// Initializes an HTTP cookie object using the provided properties.
  const NSHttpCookie.withProperties(this.properties);

  /// Properties of the new cookie object.
  final Map<NSHttpCookiePropertyKey, Object> properties;
}

/// The root class of most Objective-C class hierarchies.
@immutable
class NSObject with Copyable {
  /// Constructs a [NSObject] without creating the associated
  /// Objective-C object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  NSObject.detached({
    this.observeValue,
    BinaryMessenger? binaryMessenger,
    InstanceManager? instanceManager,
  }) : _api = NSObjectHostApiImpl(
          binaryMessenger: binaryMessenger,
          instanceManager: instanceManager,
        ) {
    // Ensures FlutterApis for the Foundation library are set up.
    FoundationFlutterApis.instance.ensureSetUp();
  }

  /// Release the reference to the Objective-C object.
  static void dispose(NSObject instance) {
    instance._api.instanceManager.removeWeakReference(instance);
  }

  /// Global instance of [InstanceManager].
  static final InstanceManager globalInstanceManager =
      InstanceManager(onWeakReferenceRemoved: (int instanceId) {
    NSObjectHostApiImpl().dispose(instanceId);
  });

  final NSObjectHostApiImpl _api;

  /// Informs the observing object when the value at the specified key path has
  /// changed.
  ///
  /// {@template webview_flutter_wkwebview.foundation.callbacks}
  /// For the associated Objective-C object to be automatically garbage
  /// collected, it is required that this Function doesn't contain a strong
  /// reference to the encapsulating class instance. Consider using
  /// `WeakReference` when referencing an object not received as a parameter.
  /// Otherwise, use [NSObject.dispose] to release the associated Objective-C
  /// object manually.
  ///
  /// See [withWeakRefenceTo].
  /// {@endtemplate}
  final void Function(
    String keyPath,
    NSObject object,
    Map<NSKeyValueChangeKey, Object?> change,
  )? observeValue;

  /// Registers the observer object to receive KVO notifications.
  Future<void> addObserver(
    NSObject observer, {
    required String keyPath,
    required Set<NSKeyValueObservingOptions> options,
  }) {
    assert(options.isNotEmpty);
    return _api.addObserverForInstances(
      this,
      observer,
      keyPath,
      options,
    );
  }

  /// Stops the observer object from receiving change notifications for the property.
  Future<void> removeObserver(NSObject observer, {required String keyPath}) {
    return _api.removeObserverForInstances(this, observer, keyPath);
  }

  @override
  NSObject copy() {
    return NSObject.detached(
      observeValue: observeValue,
      binaryMessenger: _api.binaryMessenger,
      instanceManager: _api.instanceManager,
    );
  }
}
