// 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:convert';

import 'package:flutter/services.dart' as flt;
import 'package:flutter_driver/driver_extension.dart';
import 'package:flutter_driver/flutter_driver.dart';
import 'package:flutter_test/flutter_test.dart';

import 'src/common.dart';

/// An extension that forwards [NativeCommand]s to a registered plugin.
const CommandExtension nativeDriverCommands = NativeDriverCommandExtension(
  flt.MethodChannel('native_driver'),
);

/// An extension that forwards [NativeCommand]s to a registered plugin.
///
/// This extension is used to communicate with a platform plugin, and relays
/// [NativeCommand]s to the platform plugin, and resolves the result as a
/// [NativeResult], both thin wrappers around a `Map<String, Object?>` (JSON
/// compatible object).
///
/// A singleton default instance of this class is [nativeDriverCommands].
final class NativeDriverCommandExtension implements CommandExtension {
  /// Creates a new [NativeDriverCommandExtension] with the given [channel].
  ///
  /// Can be used in exceptional cases where a custom [MethodChannel] is needed;
  /// otherwise, use the singleton [nativeDriverCommands].
  const NativeDriverCommandExtension(this._channel);
  final flt.MethodChannel _channel;

  @override
  Future<Result> call(
    Command command,
    WidgetController prober,
    CreateFinderFactory finderFactory,
    CommandHandlerFactory handlerFactory,
  ) async {
    if (command is! NativeCommand) {
      throw ArgumentError.value(command, 'command', 'Expected a NativeCommand');
    }
    if (await _builtInCall(command.method) case final Result result) {
      return result;
    }
    final Object? result = await _channel.invokeMethod<Object>(
      command.method,
      command.arguments,
    );
    if (result == null) {
      return const _MethodChannelResult(<String, Object?>{});
    }
    if (result is! Map<String, Object?>) {
      throw ArgumentError.value(
        result,
        'result',
        'Expected a Map<String, Object?>',
      );
    }
    return _MethodChannelResult(result);
  }

  // While these could have been implemented in native code, they are already
  // available as engine-bundled platform plugins, so using them directly
  // reduces the amount of code to be written and maintained.
  Future<Result?> _builtInCall(String method) async {
    switch (method) {
      case 'rotate_landscape':
        await flt.SystemChrome.setPreferredOrientations(
          const <flt.DeviceOrientation>[flt.DeviceOrientation.landscapeLeft],
        );
        return Result.empty;
      case 'rotate_default':
        await flt.SystemChrome.setPreferredOrientations(
          const <flt.DeviceOrientation>[],
        );
        return Result.empty;
      default:
        return null;
    }
  }

  @override
  String get commandKind => 'native_driver';

  @override
  NativeCommand deserialize(
    Map<String, String> params,
    DeserializeFinderFactory finderFactory,
    DeserializeCommandFactory commandFactory,
  ) {
    final String? method = params['method'];
    if (method == null) {
      throw ArgumentError.value(params, 'params', 'Missing method');
    }
    final String? arguments = params['arguments'];
    final Map<String, Object?>? decoded;
    if (arguments == null) {
      decoded = null;
    } else {
      final Object? intermediate = json.decode(arguments);
      if (intermediate is! Map<String, Object?>) {
        throw ArgumentError.value(
          arguments,
          'arguments',
          'Expected a Map<String, Object?>',
        );
      }
      decoded = intermediate;
    }
    return NativeCommand(method, arguments: decoded);
  }
}

final class _MethodChannelResult implements Result {
  const _MethodChannelResult(this._json);
  final Map<String, Object?> _json;

  @override
  Map<String, Object?> toJson() => _json;
}
