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

/// Classes shared between `integration_test.dart` and `flutter drive` based
/// adoptor (ex: `integration_test_driver.dart`).

/// An object sent from integration_test back to the Flutter Driver in response to
/// `request_data` command.
class Response {
  final List<Failure> _failureDetails;

  final bool _allTestsPassed;

  /// The extra information to be added along side the test result.
  Map<String, dynamic> data;

  /// Constructor to use for positive response.
  Response.allTestsPassed({this.data})
      : this._allTestsPassed = true,
        this._failureDetails = null;

  /// Constructor for failure response.
  Response.someTestsFailed(this._failureDetails, {this.data})
      : this._allTestsPassed = false;

  /// Constructor for failure response.
  Response.toolException({String ex})
      : this._allTestsPassed = false,
        this._failureDetails = [Failure('ToolException', ex)];

  /// Constructor for web driver commands response.
  Response.webDriverCommand({this.data})
      : this._allTestsPassed = false,
        this._failureDetails = null;

  /// Whether the test ran successfully or not.
  bool get allTestsPassed => _allTestsPassed;

  /// If the result are failures get the formatted details.
  String get formattedFailureDetails =>
      _allTestsPassed ? '' : formatFailures(_failureDetails);

  /// Failure details as a list.
  List<Failure> get failureDetails => _failureDetails;

  /// Serializes this message to a JSON map.
  String toJson() => json.encode(<String, dynamic>{
        'result': allTestsPassed.toString(),
        'failureDetails': _failureDetailsAsString(),
        if (data != null) 'data': data
      });

  /// Deserializes the result from JSON.
  static Response fromJson(String source) {
    final Map<String, dynamic> responseJson = json.decode(source);
    if (responseJson['result'] as String == 'true') {
      return Response.allTestsPassed(data: responseJson['data']);
    } else {
      return Response.someTestsFailed(
        _failureDetailsFromJson(responseJson['failureDetails']),
        data: responseJson['data'],
      );
    }
  }

  /// Method for formatting the test failures' details.
  String formatFailures(List<Failure> failureDetails) {
    if (failureDetails.isEmpty) {
      return '';
    }

    StringBuffer sb = StringBuffer();
    int failureCount = 1;
    failureDetails.forEach((Failure f) {
      sb.writeln('Failure in method: ${f.methodName}');
      sb.writeln('${f.details}');
      sb.writeln('end of failure ${failureCount.toString()}\n\n');
      failureCount++;
    });
    return sb.toString();
  }

  /// Create a list of Strings from [_failureDetails].
  List<String> _failureDetailsAsString() {
    final List<String> list = List<String>();
    if (_failureDetails == null || _failureDetails.isEmpty) {
      return list;
    }

    _failureDetails.forEach((Failure f) {
      list.add(f.toJson());
    });

    return list;
  }

  /// Creates a [Failure] list using a json response.
  static List<Failure> _failureDetailsFromJson(List<dynamic> list) {
    final List<Failure> failureList = List<Failure>();
    list.forEach((s) {
      final String failure = s as String;
      failureList.add(Failure.fromJsonString(failure));
    });
    return failureList;
  }
}

/// Representing a failure includes the method name and the failure details.
class Failure {
  /// The name of the test method which failed.
  final String methodName;

  /// The details of the failure such as stack trace.
  final String details;

  /// Constructor requiring all fields during initialization.
  Failure(this.methodName, this.details);

  /// Serializes the object to JSON.
  String toJson() {
    return json.encode(<String, String>{
      'methodName': methodName,
      'details': details,
    });
  }

  @override
  String toString() => toJson();

  /// Decode a JSON string to create a Failure object.
  static Failure fromJsonString(String jsonString) {
    Map<String, dynamic> failure = json.decode(jsonString);
    return Failure(failure['methodName'], failure['details']);
  }
}

/// Message used to communicate between app side tests and driver tests.
///
/// Not all `integration_tests` use this message. They are only used when app
/// side tests are sending [WebDriverCommand]s to the driver side.
///
/// These messages are used for the handshake since they carry information on
/// the driver side test such as: status pending or tests failed.
class DriverTestMessage {
  final bool _isSuccess;
  final bool _isPending;

  /// When tests are failed on the driver side.
  DriverTestMessage.error()
      : _isSuccess = false,
        _isPending = false;

  /// When driver side is waiting on [WebDriverCommand]s to be sent from the
  /// app side.
  DriverTestMessage.pending()
      : _isSuccess = false,
        _isPending = true;

  /// When driver side successfully completed executing the [WebDriverCommand].
  DriverTestMessage.complete()
      : _isSuccess = true,
        _isPending = false;

  // /// Status of this message.
  // ///
  // /// The status will be use to notify `integration_test` of driver side's
  // /// state.
  // String get status => _status;

  /// Has the command completed successfully by the driver.
  bool get isSuccess => _isSuccess;

  /// Is the driver waiting for a command.
  bool get isPending => _isPending;

  /// Depending on the values of [isPending] and [isSuccess], returns a string
  /// to represent the [DriverTestMessage].
  ///
  /// Used as an alternative method to converting the object to json since
  /// [RequestData] is only accepting string as `message`.
  @override
  String toString() {
    if (isPending) {
      return 'pending';
    } else if (isSuccess) {
      return 'complete';
    } else {
      return 'error';
    }
  }

  /// Return a DriverTestMessage depending on `status`.
  static DriverTestMessage fromString(String status) {
    switch (status) {
      case 'error':
        return DriverTestMessage.error();
      case 'pending':
        return DriverTestMessage.pending();
      case 'complete':
        return DriverTestMessage.complete();
      default:
        throw StateError('This type of status does not exist: $status');
    }
  }
}

/// Types of different WebDriver commands that can be used in web integration
/// tests.
///
/// These commands are either commands that WebDriver can execute or used
/// for the communication between `integration_test` and the driver test.
enum WebDriverCommandType {
  /// Acknowlegement for the previously sent message.
  ack,

  /// No further WebDriver commands is requested by the app-side tests.
  noop,

  /// Asking WebDriver to take a screenshot of the Web page.
  screenshot,
}

/// Command for WebDriver to execute.
///
/// Only works on Web when tests are run via `flutter driver` command.
///
/// See: https://www.w3.org/TR/webdriver/
class WebDriverCommand {
  /// Type of the [WebDriverCommand].
  ///
  /// Currently the only command that triggers a WebDriver API is `screenshot`.
  ///
  /// There are also `ack` and `noop` commands defined to manage the handshake
  /// during the communication.
  final WebDriverCommandType type;

  /// Used for adding extra values to the commands such as file name for
  /// `screenshot`.
  final Map<String, dynamic> values;

  /// Constructor for [WebDriverCommandType.noop] command.
  WebDriverCommand.noop()
      : this.type = WebDriverCommandType.noop,
        this.values = Map();

  /// Constructor for [WebDriverCommandType.noop] screenshot.
  WebDriverCommand.screenshot(String screenshot_name)
      : this.type = WebDriverCommandType.screenshot,
        this.values = {'screenshot_name': screenshot_name};

  /// Util method for converting [WebDriverCommandType] to a map entry.
  ///
  /// Used for converting messages to json format.
  static Map<String, dynamic> typeToMap(WebDriverCommandType type) => {
        'web_driver_command': '${type}',
      };
}

/// Template methods each class that responses the driver side inputs must
/// implement.
///
/// Depending on the platform the communication between `integration_tests` and
/// the `driver_tests` can be different.
///
/// For the web implementation [WebCallbackManager].
/// For the io implementation [IOCallbackManager].
abstract class CallbackManager {
  /// The callback function to response the driver side input.
  Future<Map<String, dynamic>> callback(
      Map<String, String> params, IntegrationTestResults testRunner);

  /// Request to take a screenshot of the application.
  Future<void> takeScreenshot(String screenshot);

  /// Cleanup and completers or locks used during the communication.
  void cleanup();
}

/// Interface that surfaces test results of integration tests.
///
/// Implemented by [IntegrationTestWidgetsFlutterBinding]s.
///
/// Any class which needs to access the test results but do not want to create
/// a cyclic dependency [IntegrationTestWidgetsFlutterBinding]s can use this
/// interface. Example [CallbackManager].
abstract class IntegrationTestResults {
  /// Stores failure details.
  ///
  /// Failed test method's names used as key.
  List<Failure> get failureMethodsDetails;

  /// The extra data for the reported result.
  Map<String, dynamic> get reportData;

  /// Whether all the test methods completed succesfully.
  Completer<bool> get allTestsPassed;
}
