// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. 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:io';

import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';

import '../../backend/group.dart';
import '../../backend/metadata.dart';
import '../../backend/test.dart';
import '../../backend/test_platform.dart';
import '../../util/io.dart';
import '../../util/remote_exception.dart';
import '../application_exception.dart';
import '../configuration.dart';
import '../configuration/suite.dart';
import '../environment.dart';
import '../load_exception.dart';
import '../runner_suite.dart';
import '../runner_test.dart';

typedef StackTrace _MapTrace(StackTrace trace);

final _deserializeTimeout = new Duration(minutes: 3);

/// A helper method for creating a [RunnerSuiteController] containing tests
/// that communicate over [channel].
///
/// This returns a controller so that the caller has a chance to control the
/// runner suite's debugging state based on plugin-specific logic.
///
/// If the suite is closed, this will close [channel].
///
/// If [mapTrace] is passed, it will be used to adjust stack traces for any
/// errors emitted by tests.
///
/// If [asciiSymbols] is passed, it controls whether the `symbol` package is
/// configured to use plain ASCII or Unicode symbols. It defaults to `true` on
/// Windows and `false` elsewhere.
Future<RunnerSuiteController> deserializeSuite(
    String path,
    TestPlatform platform,
    SuiteConfiguration suiteConfig,
    Environment environment,
    StreamChannel channel,
    {StackTrace mapTrace(StackTrace trace)}) async {
  if (mapTrace == null) mapTrace = (trace) => trace;

  var disconnector = new Disconnector();
  var suiteChannel = new MultiChannel(channel.transform(disconnector));

  suiteChannel.sink.add({
    'platform': platform.identifier,
    'metadata': suiteConfig.metadata.serialize(),
    'os': platform == TestPlatform.vm ? currentOS.identifier : null,
    'asciiGlyphs': Platform.isWindows,
    'path': path,
    'collectTraces': Configuration.current.reporter == 'json',
    'noRetry': Configuration.current.noRetry,
  });

  var completer = new Completer();

  var loadSuiteZone = Zone.current;
  handleError(error, stackTrace) {
    disconnector.disconnect();

    if (completer.isCompleted) {
      // If we've already provided a controller, send the error to the
      // LoadSuite. This will cause the virtual load test to fail, which will
      // notify the user of the error.
      loadSuiteZone.handleUncaughtError(error, mapTrace(stackTrace));
    } else {
      completer.completeError(error, mapTrace(stackTrace));
    }
  }

  suiteChannel.stream.listen(
      (response) {
        switch (response["type"]) {
          case "print":
            print(response["line"]);
            break;

          case "loadException":
            handleError(new LoadException(path, response["message"]),
                new Trace.current());
            break;

          case "error":
            var asyncError = RemoteException.deserialize(response["error"]);
            handleError(new LoadException(path, asyncError.error),
                mapTrace(asyncError.stackTrace));
            break;

          case "success":
            var deserializer = new _Deserializer(suiteChannel, mapTrace);
            completer.complete(deserializer.deserializeGroup(response["root"]));
            break;
        }
      },
      onError: handleError,
      onDone: () {
        if (completer.isCompleted) return;
        completer.completeError(
            new LoadException(
                path, "Connection closed before test suite loaded."),
            new Trace.current());
      });

  return new RunnerSuiteController(
      environment,
      suiteConfig,
      await completer.future.timeout(_deserializeTimeout, onTimeout: () {
        throw new ApplicationException(
            "Timed out while loading the test suite.\n"
            "It's likely that there's a missing import or syntax error.");
      }),
      path: path,
      platform: platform,
      os: currentOS,
      onClose: () => disconnector.disconnect().catchError(handleError));
}

/// A utility class for storing state while deserializing tests.
class _Deserializer {
  /// The channel over which tests communicate.
  final MultiChannel _channel;

  /// The function used to errors' map stack traces.
  final _MapTrace _mapTrace;

  _Deserializer(this._channel, this._mapTrace);

  /// Deserializes [group] into a concrete [Group].
  Group deserializeGroup(Map group) {
    var metadata = new Metadata.deserialize(group['metadata']);
    return new Group(
        group['name'],
        (group['entries'] as List).map((entry) {
          var map = entry as Map;
          if (map['type'] == 'group') return deserializeGroup(map);
          return _deserializeTest(map);
        }),
        metadata: metadata,
        trace: group['trace'] == null ? null : new Trace.parse(group['trace']),
        setUpAll: _deserializeTest(group['setUpAll']),
        tearDownAll: _deserializeTest(group['tearDownAll']));
  }

  /// Deserializes [test] into a concrete [Test] class.
  ///
  /// Returns `null` if [test] is `null`.
  Test _deserializeTest(Map test) {
    if (test == null) return null;

    var metadata = new Metadata.deserialize(test['metadata']);
    var trace = test['trace'] == null ? null : new Trace.parse(test['trace']);
    var testChannel = _channel.virtualChannel(test['channel']);
    return new RunnerTest(
        test['name'], metadata, trace, testChannel, _mapTrace);
  }
}
