// Copyright 2014 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.


import 'dart:typed_data';

import 'package:flutter/foundation.dart';

import 'platform_channel.dart';

export 'dart:typed_data' show ByteData;

/// A message encoding/decoding mechanism.
///
/// Both operations throw an exception, if conversion fails. Such situations
/// should be treated as programming errors.
///
/// See also:
///
///  * [BasicMessageChannel], which use [MessageCodec]s for communication
///    between Flutter and platform plugins.
abstract class MessageCodec<T> {
  /// Encodes the specified [message] in binary.
  ///
  /// Returns null if the message is null.
  ByteData? encodeMessage(T message);

  /// Decodes the specified [message] from binary.
  ///
  /// Returns null if the message is null.
  T? decodeMessage(ByteData? message);
}

/// An command object representing the invocation of a named method.
@immutable
class MethodCall {
  /// Creates a [MethodCall] representing the invocation of [method] with the
  /// specified [arguments].
  const MethodCall(this.method, [this.arguments])
    : assert(method != null);

  /// The name of the method to be called.
  final String method;

  /// The arguments for the method.
  ///
  /// Must be a valid value for the [MethodCodec] used.
  ///
  /// This property is `dynamic`, which means type-checking is skipped when accessing
  /// this property. To minimize the risk of type errors at runtime, the value should
  /// be cast to `Object?` when accessed.
  final dynamic arguments;

  @override
  String toString() => '${objectRuntimeType(this, 'MethodCall')}($method, $arguments)';
}

/// A codec for method calls and enveloped results.
///
/// All operations throw an exception, if conversion fails.
///
/// See also:
///
///  * [MethodChannel], which use [MethodCodec]s for communication
///    between Flutter and platform plugins.
///  * [EventChannel], which use [MethodCodec]s for communication
///    between Flutter and platform plugins.
abstract class MethodCodec {
  /// Encodes the specified [methodCall] into binary.
  ByteData encodeMethodCall(MethodCall methodCall);

  /// Decodes the specified [methodCall] from binary.
  MethodCall decodeMethodCall(ByteData? methodCall);

  /// Decodes the specified result [envelope] from binary.
  ///
  /// Throws [PlatformException], if [envelope] represents an error, otherwise
  /// returns the enveloped result.
  ///
  /// The type returned from [decodeEnvelope] is `dynamic` (not `Object?`),
  /// which means *no type checking is performed on its return value*. It is
  /// strongly recommended that the return value be immediately cast to a known
  /// type to prevent runtime errors due to typos that the type checker could
  /// otherwise catch.
  dynamic decodeEnvelope(ByteData envelope);

  /// Encodes a successful [result] into a binary envelope.
  ByteData encodeSuccessEnvelope(Object? result);

  /// Encodes an error result into a binary envelope.
  ///
  /// The specified error [code], human-readable error [message] and error
  /// [details] correspond to the fields of [PlatformException].
  ByteData encodeErrorEnvelope({ required String code, String? message, Object? details});
}


/// Thrown to indicate that a platform interaction failed in the platform
/// plugin.
///
/// See also:
///
///  * [MethodCodec], which throws a [PlatformException], if a received result
///    envelope represents an error.
///  * [MethodChannel.invokeMethod], which completes the returned future
///    with a [PlatformException], if invoking the platform plugin method
///    results in an error envelope.
///  * [EventChannel.receiveBroadcastStream], which emits
///    [PlatformException]s as error events, whenever an event received from the
///    platform plugin is wrapped in an error envelope.
class PlatformException implements Exception {
  /// Creates a [PlatformException] with the specified error [code] and optional
  /// [message], and with the optional error [details] which must be a valid
  /// value for the [MethodCodec] involved in the interaction.
  PlatformException({
    required this.code,
    this.message,
    this.details,
    this.stacktrace,
  }) : assert(code != null);

  /// An error code.
  final String code;

  /// A human-readable error message, possibly null.
  final String? message;

  /// Error details, possibly null.
  ///
  /// This property is `dynamic`, which means type-checking is skipped when accessing
  /// this property. To minimize the risk of type errors at runtime, the value should
  /// be cast to `Object?` when accessed.
  final dynamic details;

  /// Native stacktrace for the error, possibly null.
  ///
  /// This contains the native platform stack trace, not the Dart stack trace.
  ///
  /// The stack trace for Dart exceptions can be obtained using try-catch blocks, for example:
  ///
  /// ```dart
  /// try {
  ///   ...
  /// } catch (e, stacktrace) {
  ///   print(stacktrace);
  /// }
  /// ```
  final String? stacktrace;

  @override
  String toString() => 'PlatformException($code, $message, $details, $stacktrace)';
}

/// Thrown to indicate that a platform interaction failed to find a handling
/// plugin.
///
/// See also:
///
///  * [MethodChannel.invokeMethod], which completes the returned future
///    with a [MissingPluginException], if no plugin handler for the method call
///    was found.
///  * [OptionalMethodChannel.invokeMethod], which completes the returned future
///    with null, if no plugin handler for the method call was found.
class MissingPluginException implements Exception {
  /// Creates a [MissingPluginException] with an optional human-readable
  /// error message.
  MissingPluginException([this.message]);

  /// A human-readable error message, possibly null.
  final String? message;

  @override
  String toString() => 'MissingPluginException($message)';
}
