// Copyright (c) 2015, 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.

library test.runner.loader;

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:analyzer/analyzer.dart' hide Configuration;
import 'package:async/async.dart';
import 'package:path/path.dart' as p;
import 'package:stack_trace/stack_trace.dart';

import '../backend/group.dart';
import '../backend/metadata.dart';
import '../backend/test.dart';
import '../backend/test_platform.dart';
import '../util/dart.dart' as dart;
import '../util/io.dart';
import '../util/remote_exception.dart';
import '../utils.dart';
import 'browser/server.dart';
import 'configuration.dart';
import 'hack_load_vm_file_hook.dart';
import 'load_exception.dart';
import 'load_suite.dart';
import 'parse_metadata.dart';
import 'runner_suite.dart';
import 'vm/environment.dart';
import 'vm/isolate_test.dart';

/// A class for finding test files and loading them into a runnable form.
class Loader {
  /// The test runner configuration.
  final Configuration _config;

  /// The root directory that will be served for browser tests.
  final String _root;

  /// All suites that have been created by the loader.
  final _suites = new Set<RunnerSuite>();

  /// The server that serves browser test pages.
  ///
  /// This is lazily initialized the first time it's accessed.
  Future<BrowserServer> get _browserServer {
    return _browserServerMemo.runOnce(() {
      return BrowserServer.start(_config, root: _root);
    });
  }
  final _browserServerMemo = new AsyncMemoizer<BrowserServer>();

  /// The memoizer for running [close] exactly once.
  final _closeMemo = new AsyncMemoizer();

  /// Creates a new loader that loads tests on platforms defined in [_config].
  ///
  /// [root] is the root directory that will be served for browser tests. It
  /// defaults to the working directory.
  Loader(this._config, {String root})
      : _root = root == null ? p.current : root;

  /// Loads all test suites in [dir].
  ///
  /// This will load tests from files that end in "_test.dart". Any tests that
  /// fail to load will be emitted as [LoadException]s.
  ///
  /// This emits [LoadSuite]s that must then be run to emit the actual
  /// [RunnerSuite]s defined in the file.
  Stream<LoadSuite> loadDir(String dir) {
    return mergeStreams(new Directory(dir).listSync(recursive: true)
        .map((entry) {
      if (entry is! File) return new Stream.fromIterable([]);

      if (!entry.path.endsWith("_test.dart")) {
        return new Stream.fromIterable([]);
      }

      if (p.split(entry.path).contains('packages')) {
         return new Stream.fromIterable([]);
      }

      return loadFile(entry.path);
    }));
  }

  /// Loads a test suite from the file at [path].
  ///
  /// This emits [LoadSuite]s that must then be run to emit the actual
  /// [RunnerSuite]s defined in the file.
  ///
  /// This will emit a [LoadException] if the file fails to load.
  Stream<LoadSuite> loadFile(String path) async* {
    var suiteMetadata;
    try {
      suiteMetadata = parseMetadata(path);
    } on AnalyzerErrorGroup catch (_) {
      // Ignore the analyzer's error, since its formatting is much worse than
      // the VM's or dart2js's.
      suiteMetadata = new Metadata();
    } on FormatException catch (error, stackTrace) {
      yield new LoadSuite.forLoadException(
          new LoadException(path, error), stackTrace: stackTrace);
      return;
    }
    suiteMetadata = _config.metadata.merge(suiteMetadata);

    if (_config.pubServeUrl != null && !p.isWithin('test', path)) {
      yield new LoadSuite.forLoadException(new LoadException(
          path, 'When using "pub serve", all test files must be in test/.'));
      return;
    }

    for (var platform in _config.platforms) {
      if (!suiteMetadata.testOn.evaluate(platform, os: currentOS)) continue;

      var metadata = suiteMetadata.forPlatform(platform, os: currentOS);

      // Don't load a skipped suite.
      if (metadata.skip) {
        yield new LoadSuite.forSuite(new RunnerSuite(
            const VMEnvironment(),
            new Group.root([], metadata: metadata),
            path: path, platform: platform));
        continue;
      }

      var name = (platform.isJS ? "compiling " : "loading ") + path;
      yield new LoadSuite(name, () {
        return platform == TestPlatform.vm
            ? _loadVmFile(path, metadata)
            : _loadBrowserFile(path, platform, metadata);
      }, platform: platform);
    }
  }

  /// Load the test suite at [path] in [platform].
  ///
  /// [metadata] is the suite-level metadata for the test.
  Future<RunnerSuite> _loadBrowserFile(String path, TestPlatform platform,
        Metadata metadata) async =>
      (await _browserServer).loadSuite(path, platform, metadata);

  /// Load the test suite at [path] in VM isolate.
  ///
  /// [metadata] is the suite-level metadata for the test.
  Future<RunnerSuite> _loadVmFile(String path, Metadata metadata) async {
    if (loadVMFileHook != null) {
      var suite = await loadVMFileHook(path, metadata, _config);
      _suites.add(suite);
      return suite;
    }

    var receivePort = new ReceivePort();

    var isolate;
    try {
      if (_config.pubServeUrl != null) {
        var url = _config.pubServeUrl.resolveUri(
            p.toUri(p.relative(path, from: 'test') + '.vm_test.dart'));

        try {
          isolate = await Isolate.spawnUri(url, [], {
            'reply': receivePort.sendPort,
            'metadata': metadata.serialize()
          }, checked: true);
        } on IsolateSpawnException catch (error) {
          if (error.message.contains("OS Error: Connection refused") ||
              error.message.contains("The remote computer refused")) {
            throw new LoadException(path,
                "Error getting $url: Connection refused\n"
                'Make sure "pub serve" is running.');
          } else if (error.message.contains("404 Not Found")) {
            throw new LoadException(path,
                "Error getting $url: 404 Not Found\n"
                'Make sure "pub serve" is serving the test/ directory.');
          }

          throw new LoadException(path, error);
        }
      } else {
        isolate = await dart.runInIsolate('''
import "package:test/src/backend/metadata.dart";
import "package:test/src/runner/vm/isolate_listener.dart";

import "${p.toUri(p.absolute(path))}" as test;

void main(_, Map message) {
  var sendPort = message['reply'];
  var metadata = new Metadata.deserialize(message['metadata']);
  IsolateListener.start(sendPort, metadata, () => test.main);
}
''', {
          'reply': receivePort.sendPort,
          'metadata': metadata.serialize()
        }, packageRoot: p.toUri(_config.packageRoot), checked: true);
      }
    } catch (error, stackTrace) {
      receivePort.close();
      if (error is LoadException) rethrow;
      await new Future.error(new LoadException(path, error), stackTrace);
    }

    var completer = new Completer();

    var subscription = receivePort.listen((response) {
      if (response["type"] == "print") {
        print(response["line"]);
      } else if (response["type"] == "loadException") {
        isolate.kill();
        completer.completeError(
            new LoadException(path, response["message"]),
            new Trace.current());
      } else if (response["type"] == "error") {
        isolate.kill();
        var asyncError = RemoteException.deserialize(response["error"]);
        completer.completeError(
            new LoadException(path, asyncError.error),
            asyncError.stackTrace);
      } else {
        assert(response["type"] == "success");
        completer.complete(response["root"]);
      }
    });

    try {
      var suite = new RunnerSuite(
          const VMEnvironment(),
          _deserializeGroup(await completer.future),
          path: path,
          platform: TestPlatform.vm,
          os: currentOS,
          onClose: isolate.kill);
      _suites.add(suite);
      return suite;
    } finally {
      subscription.cancel();
    }
  }

  /// Deserializes [group] into a concrete [Group] class.
  Group _deserializeGroup(Map group) {
    var metadata = new Metadata.deserialize(group['metadata']);
    return new Group(group['name'], group['entries'].map((entry) {
      if (entry['type'] == 'group') return _deserializeGroup(entry);
      return _deserializeTest(entry);
    }),
        metadata: metadata,
        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']);
    return new IsolateTest(test['name'], metadata, test['sendPort']);
  }

  /// Closes the loader and releases all resources allocated by it.
  Future close() {
    return _closeMemo.runOnce(() async {
      await Future.wait(_suites.map((suite) => suite.close()));
      _suites.clear();

      if (!_browserServerMemo.hasRun) return;
      await (await _browserServer).close();
    });
  }
}
