// Copyright 2016 The Chromium 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:async';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/src/instrumentation.dart';
import 'package:flutter_test/src/test_pointer.dart';

import 'error.dart';
import 'find.dart';
import 'gesture.dart';
import 'health.dart';
import 'message.dart';

const String _extensionMethodName = 'driver';
const String _extensionMethod = 'ext.flutter.$_extensionMethodName';
const Duration _kDefaultTimeout = const Duration(seconds: 5);

class _DriverBinding extends WidgetFlutterBinding {
  @override
  void initServiceExtensions() {
    super.initServiceExtensions();
    FlutterDriverExtension extension = new FlutterDriverExtension();
    registerServiceExtension(
      name: _extensionMethodName,
      callback: extension.call
    );
  }
}

/// Enables Flutter Driver VM service extension.
///
/// This extension is required for tests that use `package:flutter_driver` to
/// drive applications from a separate process.
///
/// Call this function prior to running your application, e.g. before you call
/// `runApp`.
void enableFlutterDriverExtension() {
  assert(WidgetFlutterBinding.instance == null);
  new _DriverBinding();
  assert(WidgetFlutterBinding.instance is _DriverBinding);
}

/// Handles a command and returns a result.
typedef Future<Result> CommandHandlerCallback(Command c);

/// Deserializes JSON map to a command object.
typedef Command CommandDeserializerCallback(Map<String, String> params);

/// Runs the finder and returns the [Element] found, or `null`.
typedef Future<Element> FinderCallback(SerializableFinder finder);

class FlutterDriverExtension {
  static final Logger _log = new Logger('FlutterDriverExtension');

  FlutterDriverExtension() {
    _commandHandlers.addAll(<String, CommandHandlerCallback>{
      'get_health': getHealth,
      'tap': tap,
      'get_text': getText,
      'scroll': scroll,
      'waitFor': waitFor,
    });

    _commandDeserializers.addAll(<String, CommandDeserializerCallback>{
      'get_health': GetHealth.deserialize,
      'tap': Tap.deserialize,
      'get_text': GetText.deserialize,
      'scroll': Scroll.deserialize,
      'waitFor': WaitFor.deserialize,
    });

    _finders.addAll(<String, FinderCallback>{
      'ByValueKey': _findByValueKey,
      'ByTooltipMessage': _findByTooltipMessage,
      'ByText': _findByText,
    });
  }

  final Instrumentation prober = new Instrumentation();
  final Map<String, CommandHandlerCallback> _commandHandlers = <String, CommandHandlerCallback>{};
  final Map<String, CommandDeserializerCallback> _commandDeserializers = <String, CommandDeserializerCallback>{};
  final Map<String, FinderCallback> _finders = <String, FinderCallback>{};

  Future<Map<String, dynamic>> call(Map<String, String> params) async {
    try {
      String commandKind = params['command'];
      CommandHandlerCallback commandHandler = _commandHandlers[commandKind];
      CommandDeserializerCallback commandDeserializer =
          _commandDeserializers[commandKind];
      if (commandHandler == null || commandDeserializer == null)
        throw 'Extension $_extensionMethod does not support command $commandKind';
      Command command = commandDeserializer(params);
      return (await commandHandler(command)).toJson();
    } catch (error, stackTrace) {
      _log.error('Uncaught extension error: $error\n$stackTrace');
      rethrow;
    }
  }

  Stream<Duration> _onFrameReadyStream;
  Stream<Duration> get _onFrameReady {
    if (_onFrameReadyStream == null) {
      // Lazy-initialize the frame callback because the renderer is not yet
      // available at the time the extension is registered.
      StreamController<Duration> frameReadyController = new StreamController<Duration>.broadcast(sync: true);
      Scheduler.instance.addPersistentFrameCallback((Duration timestamp) {
        frameReadyController.add(timestamp);
      });
      _onFrameReadyStream = frameReadyController.stream;
    }
    return _onFrameReadyStream;
  }

  Future<Health> getHealth(GetHealth command) async => new Health(HealthStatus.ok);

  /// Runs [locator] repeatedly until it finds an [Element] or times out.
  Future<Element> _waitForElement(String descriptionGetter(), Element locator()) async {
    // Short-circuit if the element is already on the UI
    Element element = locator();
    if (element != null) {
      return element;
    }

    // No element yet, so we retry on frames rendered in the future.
    Completer<Element> completer = new Completer<Element>();
    StreamSubscription<Duration> subscription;

    Timer timeout = new Timer(_kDefaultTimeout, () {
      subscription.cancel();
      completer.completeError('Timed out waiting for ${descriptionGetter()}');
    });

    subscription = _onFrameReady.listen((Duration duration) {
      Element element = locator();
      if (element != null) {
        subscription.cancel();
        timeout.cancel();
        completer.complete(element);
      }
    });

    return completer.future;
  }

  Future<Element> _findByValueKey(ByValueKey byKey) async {
    return _waitForElement(
      () => 'element with key "${byKey.keyValue}" of type ${byKey.keyValueType}',
      () {
        return prober.findElementByKey(new ValueKey<dynamic>(byKey.keyValue));
      }
    );
  }

  Future<Element> _findByTooltipMessage(ByTooltipMessage byTooltipMessage) async {
    return _waitForElement(
      () => 'tooltip with message "${byTooltipMessage.text}" on it',
      () {
        return prober.findElement((Element element) {
          Widget widget = element.widget;

          if (widget is Tooltip)
            return widget.message == byTooltipMessage.text;

          return false;
        });
      }
    );
  }

  Future<Element> _findByText(ByText byText) async {
    return await _waitForElement(
      () => 'text "${byText.text}"',
      () {
        return prober.findText(byText.text);
      });
  }

  Future<Element> _runFinder(SerializableFinder finder) {
    FinderCallback cb = _finders[finder.finderType];

    if (cb == null)
      throw 'Unsupported finder type: ${finder.finderType}';

    return cb(finder);
  }

  Future<TapResult> tap(Tap command) async {
    Element target = await _runFinder(command.finder);
    prober.tap(target);
    return new TapResult();
  }

  Future<WaitForResult> waitFor(WaitFor command) async {
    if (await _runFinder(command.finder) != null)
      return new WaitForResult();
    else
      return null;
  }

  Future<ScrollResult> scroll(Scroll command) async {
    Element target = await _runFinder(command.finder);
    final int totalMoves = command.duration.inMicroseconds * command.frequency ~/ Duration.MICROSECONDS_PER_SECOND;
    Offset delta = new Offset(command.dx, command.dy) / totalMoves.toDouble();
    Duration pause = command.duration ~/ totalMoves;
    Point startLocation = prober.getCenter(target);
    Point currentLocation = startLocation;
    TestPointer pointer = new TestPointer(1);
    HitTestResult hitTest = new HitTestResult();

    prober.binding.hitTest(hitTest, startLocation);
    prober.binding.dispatchEvent(pointer.down(startLocation), hitTest);
    await new Future<Null>.value();  // so that down and move don't happen in the same microtask
    for (int moves = 0; moves < totalMoves; moves++) {
      currentLocation = currentLocation + delta;
      prober.binding.dispatchEvent(pointer.move(currentLocation), hitTest);
      await new Future<Null>.delayed(pause);
    }
    prober.binding.dispatchEvent(pointer.up(), hitTest);

    return new ScrollResult();
  }

  Future<GetTextResult> getText(GetText command) async {
    Element target = await _runFinder(command.finder);
    // TODO(yjbanov): support more ways to read text
    Text text = target.widget;
    return new GetTextResult(text.data);
  }
}
