// 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/services.dart';
import 'package:flutter_test/flutter_test.dart';

void checkEncoding<T>(MessageCodec<T> codec, T message, List<int> expectedBytes) {
  final ByteData encoded = codec.encodeMessage(message)!;
  expect(
    encoded.buffer.asUint8List(0, encoded.lengthInBytes),
    orderedEquals(expectedBytes),
  );
}

void checkEncodeDecode<T>(MessageCodec<T> codec, T message) {
  final ByteData? encoded = codec.encodeMessage(message);
  final T? decoded = codec.decodeMessage(encoded);
  if (message == null) {
    expect(encoded, isNull);
    expect(decoded, isNull);
  } else {
    expect(deepEquals(message, decoded), isTrue);
    final ByteData? encodedAgain = codec.encodeMessage(decoded as T);
    expect(
      encodedAgain!.buffer.asUint8List(),
      orderedEquals(encoded!.buffer.asUint8List()),
    );
  }
}

bool deepEquals(dynamic valueA, dynamic valueB) {
  if (valueA is TypedData)
    return valueB is TypedData && deepEqualsTypedData(valueA, valueB);
  if (valueA is List)
    return valueB is List && deepEqualsList(valueA, valueB);
  if (valueA is Map)
    return valueB is Map && deepEqualsMap(valueA, valueB);
  if (valueA is double && valueA.isNaN)
    return valueB is double && valueB.isNaN;
  return valueA == valueB;
}

bool deepEqualsTypedData(TypedData valueA, TypedData valueB) {
  if (valueA is ByteData) {
    return valueB is ByteData
        && deepEqualsList(valueA.buffer.asUint8List(), valueB.buffer.asUint8List());
  }
  if (valueA is Uint8List)
    return valueB is Uint8List && deepEqualsList(valueA, valueB);
  if (valueA is Int32List)
    return valueB is Int32List && deepEqualsList(valueA, valueB);
  if (valueA is Int64List)
    return valueB is Int64List && deepEqualsList(valueA, valueB);
  if (valueA is Float32List)
    return valueB is Float32List && deepEqualsList(valueA, valueB);
  if (valueA is Float64List)
    return valueB is Float64List && deepEqualsList(valueA, valueB);
  throw 'Unexpected typed data: $valueA';
}

bool deepEqualsList(List<dynamic> valueA, List<dynamic> valueB) {
  if (valueA.length != valueB.length)
    return false;
  for (int i = 0; i < valueA.length; i++) {
    if (!deepEquals(valueA[i], valueB[i]))
      return false;
  }
  return true;
}

bool deepEqualsMap(Map<dynamic, dynamic> valueA, Map<dynamic, dynamic> valueB) {
  if (valueA.length != valueB.length)
    return false;
  for (final dynamic key in valueA.keys) {
    if (!valueB.containsKey(key) || !deepEquals(valueA[key], valueB[key]))
      return false;
  }
  return true;
}
