// Copyright 2018 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 'package:collection/collection.dart';

// Android MotionEvent actions for which a pointer index is encoded in the
// unmasked action code.
const List<int> kPointerActions = <int>[
  0, // DOWN
  1, // UP
  5, // POINTER_DOWN
  6, // POINTER_UP
];

const double kDoubleErrorMargin = 0.0001;

String diffMotionEvents(
  Map<String, dynamic> originalEvent,
  Map<String, dynamic> synthesizedEvent,
) {
  final StringBuffer diff = StringBuffer();

  diffMaps(originalEvent, synthesizedEvent, diff, excludeKeys: const <String>[
    'pointerProperties', // Compared separately.
    'pointerCoords', // Compared separately.
    'source', // Unused by Flutter.
    'deviceId', // Android documentation says that's an arbitrary number that shouldn't be depended on.
    'action', // Compared separately.
  ]);

  diffActions(diff, originalEvent, synthesizedEvent);
  diffPointerProperties(diff, originalEvent, synthesizedEvent);
  diffPointerCoordsList(diff, originalEvent, synthesizedEvent);

  return diff.toString();
}

void diffActions(StringBuffer diffBuffer, Map<String, dynamic> originalEvent,
    Map<String, dynamic> synthesizedEvent) {
  final int synthesizedActionMasked =
      getActionMasked(synthesizedEvent['action']);
  final int originalActionMasked = getActionMasked(originalEvent['action']);
  final String synthesizedActionName =
      getActionName(synthesizedActionMasked, synthesizedEvent['action']);
  final String originalActionName =
      getActionName(originalActionMasked, originalEvent['action']);

  if (synthesizedActionMasked != originalActionMasked)
    diffBuffer.write(
        'action (expected: $originalActionName actual: $synthesizedActionName) ');

  if (kPointerActions.contains(originalActionMasked) &&
      originalActionMasked == synthesizedActionMasked) {
    final int originalPointer = getPointerIdx(originalEvent['action']);
    final int synthesizedPointer = getPointerIdx(synthesizedEvent['action']);
    if (originalPointer != synthesizedPointer)
      diffBuffer.write(
          'pointerIdx (expected: $originalPointer actual: $synthesizedPointer action: $originalActionName ');
  }
}

void diffPointerProperties(StringBuffer diffBuffer,
    Map<String, dynamic> originalEvent, Map<String, dynamic> synthesizedEvent) {
  final List<Map<dynamic, dynamic>> expectedList =
      originalEvent['pointerProperties'].cast<Map<dynamic, dynamic>>();
  final List<Map<dynamic, dynamic>> actualList =
      synthesizedEvent['pointerProperties'].cast<Map<dynamic, dynamic>>();

  if (expectedList.length != actualList.length) {
    diffBuffer.write(
        'pointerProperties (actual length: ${actualList.length}, expected length: ${expectedList.length} ');
    return;
  }

  for (int i = 0; i < expectedList.length; i++) {
    final Map<String, dynamic> expected =
        expectedList[i].cast<String, dynamic>();
    final Map<String, dynamic> actual = actualList[i].cast<String, dynamic>();
    diffMaps(expected, actual, diffBuffer,
        messagePrefix: '[pointerProperty $i] ');
  }
}

void diffPointerCoordsList(StringBuffer diffBuffer,
    Map<String, dynamic> originalEvent, Map<String, dynamic> synthesizedEvent) {
  final List<Map<dynamic, dynamic>> expectedList =
      originalEvent['pointerCoords'].cast<Map<dynamic, dynamic>>();
  final List<Map<dynamic, dynamic>> actualList =
      synthesizedEvent['pointerCoords'].cast<Map<dynamic, dynamic>>();

  if (expectedList.length != actualList.length) {
    diffBuffer.write(
        'pointerCoords (actual length: ${actualList.length}, expected length: ${expectedList.length} ');
    return;
  }

  for (int i = 0; i < expectedList.length; i++) {
    final Map<String, dynamic> expected =
        expectedList[i].cast<String, dynamic>();
    final Map<String, dynamic> actual = actualList[i].cast<String, dynamic>();
    diffPointerCoords(expected, actual, i, diffBuffer);
  }
}

void diffPointerCoords(Map<String, dynamic> expected,
    Map<String, dynamic> actual, int pointerIdx, StringBuffer diffBuffer) {
  diffMaps(expected, actual, diffBuffer, messagePrefix: '[pointerCoord $pointerIdx] ');
}

void diffMaps(
  Map<String, dynamic> expected,
  Map<String, dynamic> actual,
  StringBuffer diffBuffer, {
  List<String> excludeKeys = const <String>[],
  String messagePrefix = '',
}) {
  const IterableEquality<String> eq = IterableEquality<String>();
  if (!eq.equals(expected.keys, actual.keys)) {
    diffBuffer.write(
        '${messagePrefix}keys (expected: ${expected.keys} actual: ${actual.keys} ');
    return;
  }
  for (String key in expected.keys) {
    if (excludeKeys.contains(key))
      continue;
    if (doublesApproximatelyMatch(expected[key], actual[key]))
      continue;

    if (expected[key] != actual[key]) {
      diffBuffer.write(
          '$messagePrefix$key (expected: ${expected[key]} actual: ${actual[key]}) ');
    }
  }
}

int getActionMasked(int action) => action & 0xff;

int getPointerIdx(int action) => (action >> 8) & 0xff;

String getActionName(int actionMasked, int action) {
  const List<String> actionNames = <String>[
    'DOWN',
    'UP',
    'MOVE',
    'CANCEL',
    'OUTSIDE',
    'POINTER_DOWN',
    'POINTER_UP',
    'HOVER_MOVE',
    'SCROLL',
    'HOVER_ENTER',
    'HOVER_EXIT',
    'BUTTON_PRESS',
    'BUTTON_RELEASE',
  ];
  if (actionMasked < actionNames.length)
    return '${actionNames[actionMasked]}($action)';
  else
    return 'ACTION_$actionMasked';
}

bool doublesApproximatelyMatch(dynamic a, dynamic b) =>
    a is double && b is double && (a - b).abs() < kDoubleErrorMargin;
