// Copyright 2017 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 'dart:typed_data';

import 'package:flutter/material.dart';

import 'pair.dart';

enum TestStatus { ok, pending, failed, complete }

typedef Future<TestStepResult> TestStep();

const String nothing = '-';

/// Result of a test step checking a nested communication handshake
/// between the Flutter app and the platform:
///
/// - The Flutter app sends a message to the platform.
/// - The platform, on receipt, echos the message back to Flutter in a separate message.
/// - The Flutter app records the incoming message echo and replies.
/// - The platform, on receipt of reply, echos the reply back to Flutter in a separate message.
/// - The Flutter app records the incoming reply echo.
/// - The platform finally replies to the original message with another echo.
class TestStepResult {
  static const TextStyle bold = const TextStyle(fontWeight: FontWeight.bold);
  static const TestStepResult complete = const TestStepResult(
    'Test complete',
    nothing,
    TestStatus.complete,
  );

  const TestStepResult(
    this.name,
    this.description,
    this.status, {
    this.messageSent = nothing,
    this.messageEcho = nothing,
    this.messageReceived = nothing,
    this.replyEcho = nothing,
    this.error = nothing,
  });

  factory TestStepResult.fromSnapshot(AsyncSnapshot<TestStepResult> snapshot) {
    switch (snapshot.connectionState) {
      case ConnectionState.none:
        return const TestStepResult('Not started', nothing, TestStatus.ok);
      case ConnectionState.waiting:
        return const TestStepResult('Executing', nothing, TestStatus.pending);
      case ConnectionState.done:
        if (snapshot.hasData) {
          return snapshot.data;
        } else {
          final TestStepResult result = snapshot.error;
          return result;
        }
        break;
      default:
        throw 'Unsupported state ${snapshot.connectionState}';
    }
  }

  final String name;
  final String description;
  final TestStatus status;
  final dynamic messageSent;
  final dynamic messageEcho;
  final dynamic messageReceived;
  final dynamic replyEcho;
  final dynamic error;

  Widget asWidget(BuildContext context) {
    return new Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        new Text('Step: $name', style: bold),
        new Text(description),
        const Text(' '),
        new Text('Msg sent: ${_toString(messageSent)}'),
        new Text('Msg rvcd: ${_toString(messageReceived)}'),
        new Text('Reply echo: ${_toString(replyEcho)}'),
        new Text('Msg echo: ${_toString(messageEcho)}'),
        new Text('Error: ${_toString(error)}'),
        const Text(' '),
        new Text(
          status.toString().substring('TestStatus.'.length),
          key: new ValueKey<String>(
              status == TestStatus.pending ? 'nostatus' : 'status'),
          style: bold,
        ),
      ],
    );
  }
}

Future<TestStepResult> resultOfHandshake(
  String name,
  String description,
  dynamic message,
  List<dynamic> received,
  dynamic messageEcho,
  dynamic error,
) async {
  assert(message != nothing);
  while (received.length < 2)
    received.add(nothing);
  TestStatus status;
  if (!_deepEquals(messageEcho, message) ||
      received.length != 2 ||
      !_deepEquals(received[0], message) ||
      !_deepEquals(received[1], message)) {
    status = TestStatus.failed;
  } else if (error != nothing) {
    status = TestStatus.failed;
  } else {
    status = TestStatus.ok;
  }
  return new TestStepResult(
    name,
    description,
    status,
    messageSent: message,
    messageEcho: messageEcho,
    messageReceived: received[0],
    replyEcho: received[1],
    error: error,
  );
}

String _toString(dynamic message) {
  if (message is ByteData)
    return message.buffer
        .asUint8List(message.offsetInBytes, message.lengthInBytes)
        .toString();
  else
    return '$message';
}

bool _deepEquals(dynamic a, dynamic b) {
  if (a == b)
    return true;
  if (a is double && a.isNaN)
    return b is double && b.isNaN;
  if (a is ByteData)
    return b is ByteData && _deepEqualsByteData(a, b);
  if (a is List)
    return b is List && _deepEqualsList(a, b);
  if (a is Map)
    return b is Map && _deepEqualsMap(a, b);
  if (a is Pair)
    return b is Pair && _deepEqualsPair(a, b);
  return false;
}

bool _deepEqualsByteData(ByteData a, ByteData b) {
  return _deepEqualsList(
    a.buffer.asUint8List(a.offsetInBytes, a.lengthInBytes),
    b.buffer.asUint8List(b.offsetInBytes, b.lengthInBytes),
  );
}

bool _deepEqualsList(List<dynamic> a, List<dynamic> b) {
  if (a.length != b.length)
    return false;
  for (int i = 0; i < a.length; i++) {
    if (!_deepEquals(a[i], b[i]))
      return false;
  }
  return true;
}

bool _deepEqualsMap(Map<dynamic, dynamic> a, Map<dynamic, dynamic> b) {
  if (a.length != b.length)
    return false;
  for (dynamic key in a.keys) {
    if (!b.containsKey(key) || !_deepEquals(a[key], b[key]))
      return false;
  }
  return true;
}

bool _deepEqualsPair(Pair a, Pair b) {
  return _deepEquals(a.left, b.left) && _deepEquals(a.right, b.right);
}
