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

library plugin_platform_interface;

import 'package:meta/meta.dart';

/// Base class for platform interfaces.
///
/// Provides a static helper method for ensuring that platform interfaces are
/// implemented using `extends` instead of `implements`.
///
/// Platform interface classes are expected to have a private static token object which will be
/// be passed to [verifyToken] along with a platform interface object for verification.
///
/// Sample usage:
///
/// ```dart
/// abstract class UrlLauncherPlatform extends PlatformInterface {
///   UrlLauncherPlatform() : super(token: _token);
///
///   static UrlLauncherPlatform _instance = MethodChannelUrlLauncher();
///
///   static const Object _token = Object();
///
///   static UrlLauncherPlatform get instance => _instance;
///
///   /// Platform-specific plugins should set this with their own platform-specific
///   /// class that extends [UrlLauncherPlatform] when they register themselves.
///   static set instance(UrlLauncherPlatform instance) {
///     PlatformInterface.verifyToken(instance, _token);
///     _instance = instance;
///   }
///
///  }
/// ```
///
/// Mockito mocks of platform interfaces will fail the verification, in test code only it is possible
/// to include the [MockPlatformInterfaceMixin] for the verification to be temporarily disabled. See
/// [MockPlatformInterfaceMixin] for a sample of using Mockito to mock a platform interface.
abstract class PlatformInterface {
  /// Pass a private, class-specific `const Object()` as the `token`.
  PlatformInterface({required Object token}) : _instanceToken = token;

  final Object? _instanceToken;

  /// Ensures that the platform instance has a token that matches the
  /// provided token and throws [AssertionError] if not.
  ///
  /// This is used to ensure that implementers are using `extends` rather than
  /// `implements`.
  ///
  /// Subclasses of [MockPlatformInterfaceMixin] are assumed to be valid in debug
  /// builds.
  ///
  /// This is implemented as a static method so that it cannot be overridden
  /// with `noSuchMethod`.
  static void verifyToken(PlatformInterface instance, Object token) {
    if (instance is MockPlatformInterfaceMixin) {
      bool assertionsEnabled = false;
      assert(() {
        assertionsEnabled = true;
        return true;
      }());
      if (!assertionsEnabled) {
        throw AssertionError(
            '`MockPlatformInterfaceMixin` is not intended for use in release builds.');
      }
      return;
    }
    if (!identical(token, instance._instanceToken)) {
      throw AssertionError(
          'Platform interfaces must not be implemented with `implements`');
    }
  }
}

/// A [PlatformInterface] mixin that can be combined with mockito's `Mock`.
///
/// It passes the [PlatformInterface.verifyToken] check even though it isn't
/// using `extends`.
///
/// This class is intended for use in tests only.
///
/// Sample usage (assuming UrlLauncherPlatform extends [PlatformInterface]:
///
/// ```dart
/// class UrlLauncherPlatformMock extends Mock
///    with MockPlatformInterfaceMixin
///    implements UrlLauncherPlatform {}
/// ```
@visibleForTesting
abstract class MockPlatformInterfaceMixin implements PlatformInterface {}
