//#!/usr/bin/env dart
// Copyright (c) 2012, 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.

/**
 * testrunner is a program to run Dart unit tests. Unlike $DART/tools/test.dart,
 * this program is intended for 3rd parties to be able to run unit tests in
 * a batched fashion. As such, it adds some features and removes others. Some
 * of the removed features are:
 *
 *   - No support for test.status files. The assumption is that tests are
 *     expected to pass. Status file support will be added in the future.
 *   - A restricted set of runtimes. The assumption here is that the Dart
 *     libraries deal with platform dependencies, and so the primary
 *     SKUs that a user of this app would be concerned with would be
 *     Dart-native versus compiled, and client (browser) vs server. To
 *     support these, three runtimes are allowed: 'drt-dart' and 'drt-js' (for
 *     client native and client-compiled, respectively), and 'vm'
 *     (for server-side native).
 *   - No sharding of test processes.
 *
 * On the other hand, a number of features have been added:
 *
 *   - The ability to filter tests by group or name.
 *   - The ability to run tests in isolates.
 *   - The ability to customize the format of the test result messages.
 *   - The ability to list the tests available.
 *
 * By default, testrunner will run all tests in the current directory.
 * With a -R option, it will recurse into subdirectories.
 * Directories can also be specified on the command line; if
 * any are specified they will override the use of the current directory.
 * All files that match the `--test-file-pattern` will be included; by default
 * this is files with names that end in _test.dart.
 *
 * Options can be specified on the command line, via a configuration
 * file (`--config`) or via a test.config file in the test directory,
 * in decreasing order of priority.
 *
 * The three runtimes are:
 *
 *   vm - run native Dart in the VM; i.e. using $DARTSDK/dart-sdk/bin/dart.
 *   drt-dart - run native Dart in DumpRenderTree, the headless version of
 *       Dartium, which is located in $DARTSDK/chromium/DumpRenderTree, if
 *       you installed the SDK that is bundled with the editor, or available
 *       from http://gsdview.appspot.com/dartium-archive/continuous/
 *       otherwise.
 *
 *   drt-js - run Dart compiled to Javascript in DumpRenderTree.
 *
 * testrunner supports simple DOM render tests. These can use expected values
 * for the render output from DumpRenderTree, either are textual DOM
 * descriptions (`--layout-tests`) or pixel renderings (`--pixel-tests`).
 * When running layout tests, testrunner will see if there is a file with
 * a .png or a .txt extension in a directory with the same name as the
 * test file (without extension) and with the test name as the file name.
 * For example, if there is a test file foo_test.dart with tests 'test1'
 * and 'test2', it will look for foo_test/test1.txt and foo_test/test2.txt
 * for text render layout files. If these exist it will do additional checks
 * of the rendered layout; if not, the test will fail.
 *
 * Layout file (re)generation can be done using `--regenerate`. This will
 * create or update the layout files (and implicitly pass the tests).
 *
 * The wrapping and execution of test files is handled by test_pipeline.dart,
 * which is run in an isolate. The `--pipeline` argument can be used to
 * specify a different script for running a test file pipeline, allowing
 * customization of the pipeline.
 *
 * Wrapper files are created for tests in the tmp directory, which can be
 * overridden with --tempdir. These files are not removed after the tests
 * are complete, primarily to reduce the amount of times pub must be 
 * executed. You can use --clean-files to force file cleanup. The temp 
 * directories will have pubspec.yaml files auto-generated unless the 
 * original test file directories have such files; in that case the existing
 * files will be copied. Whenever a new pubspec file is copied or 
 * created pub will be run (but not otherwise - so if you want to do 
 * the equivelent of pub update you should use --clean-files and the rerun
 * the tests).
 *
 * TODO(gram): if the user has a pubspec.yaml file,  we should inspect the
 * pubspec.lock file and give useful errors:
 *  - if the lock file doesn't exit, then run pub install
 *  - if it exists and it doesn't have the required packages (unittest or
 *    browser), ask the user to add them and run pub install again.
 */

library testrunner;
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'package:args/args.dart';

part 'options.dart';
part 'utils.dart';

/** The set of [PipelineRunner]s to execute. */
List _tasks;

/** The maximum number of pipelines that can run concurrently. */
int _maxTasks;

/** The number of pipelines currently running. */
int _numTasks;

/** The index of the next pipeline runner to execute. */
int _nextTask;

/** The sink to use for high-value messages, like test results. */
IOSink _outSink;

/** The sink to use for low-value messages, like verbose output. */
IOSink _logSink;

/**
 * The last temp test directory we accessed; we use this to know if we
 * need to check the pub configuration.
 */
String _testDir;
    
/**
 * The user can specify output streams on the command line, using 'none',
 * 'stdout', 'stderr', or a file path; [getSink] will take such a name
 * and return an appropriate [IOSink].
 */
IOSink getSink(String name) {
  if (name == null || name == 'none') {
    return null;
  }
  if (name == 'stdout') {
    return stdout;
  }
  if (name == 'stderr') {
    return stderr;
  }
  var f = new File(name);
  return f.openWrite();
}

/**
 * Given a [List] of [testFiles], either print the list or create
 * and execute pipelines for the files.
 */
void processTests(Map config, List testFiles) {
  _outSink = getSink(config['out']);
  _logSink = getSink(config['log']);
  if (config['list-files']) {
    if (_outSink != null) {
      for (var i = 0; i < testFiles.length; i++) {
        _outSink.write(testFiles[i]);
        _outSink.write('\n');
      }
    }
  } else {
    _maxTasks = min(config['tasks'], testFiles.length);
    _numTasks = 0;
    _nextTask = 0;
    spawnTasks(config, testFiles);
  }
}

/**
 * Create or update a pubspec for the target test directory. We use the
 * source directory pubspec if available; otherwise we create a minimal one.
 * We return a Future if we are running pub install, or null otherwise.
 */
Future doPubConfig(Path sourcePath, String sourceDir,
                   Path targetPath, String targetDir,
                   String pub, String runtime) {
  // Make sure the target directory exists.
  var d = new Directory(targetDir);
  if (!d.existsSync()) {
    d.createSync(recursive: true);
  }

  // If the source has no pubspec, but the dest does, leave 
  // things as they are. If neither do, create one in dest.

  var sourcePubSpecName = new Path(sourceDir).append("pubspec.yaml").
      toNativePath();
  var targetPubSpecName = new Path(targetDir).append("pubspec.yaml").
      toNativePath();
  var sourcePubSpec = new File(sourcePubSpecName);
  var targetPubSpec = new File(targetPubSpecName);

  if (!sourcePubSpec.existsSync()) {
    if (targetPubSpec.existsSync()) {
      return null;
    } else {
      // Create one.
      if (runtime == 'vm') {
        writeFile(targetPubSpecName,
          "name: testrunner\ndependencies:\n  unittest: any\n");
      } else {
        writeFile(targetPubSpecName,
          "name: testrunner\ndependencies:\n  unittest: any\n  browser: any\n");
      }
    }
  } else {
    if (targetPubSpec.existsSync()) {
      // If there is a source one, and it is older than the target,
      // leave the target as is.
      if (sourcePubSpec.lastModifiedSync().millisecondsSinceEpoch <
          targetPubSpec.lastModifiedSync().millisecondsSinceEpoch) {
        return null;
      }
    }
    // Source exists and is newer than target or there is no target;
    // copy the source to the target. If there is a pubspec.lock file,
    // copy that too.
    var s = sourcePubSpec.readAsStringSync();
    targetPubSpec.writeAsStringSync(s);
    var sourcePubLock = new File(sourcePubSpecName.replaceAll(".yaml", ".lock"));
    if (sourcePubLock.existsSync()) {
      var targetPubLock =
          new File(targetPubSpecName.replaceAll(".yaml", ".lock"));
      s = sourcePubLock.readAsStringSync();
      targetPubLock.writeAsStringSync(s);
    }
  }
  // A new target pubspec was created so run pub install.
  return _processHelper(pub, [ 'install' ], workingDir: targetDir);
}

/** Execute as many tasks as possible up to the maxTasks limit. */
void spawnTasks(Map config, List testFiles) {
  var verbose = config['verbose'];
  // If we were running in the VM and the immediate flag was set, we have
  // already printed the important messages (i.e. prefixed with ###),
  // so we should skip them now.
  var skipNonVerbose = config['immediate'] && config['runtime'] == 'vm';
  while (_numTasks < _maxTasks && _nextTask < testFiles.length) {
    ++_numTasks;
    var testfile = testFiles[_nextTask++];
    config['testfile'] = testfile;
    ReceivePort port = new ReceivePort();
    port.receive((msg, _) {
      List stdout = msg[0];
      List stderr = msg[1];
      List log = msg[2];
      int exitCode = msg[3];
      writelog(stdout, _outSink, _logSink, verbose, skipNonVerbose);
      writelog(stderr, _outSink, _logSink, true, skipNonVerbose);
      writelog(log, _outSink, _logSink, verbose, skipNonVerbose);
      port.close();
      --_numTasks;
      if (exitCode == 0 || !config['stop-on-failure']) {
        spawnTasks(config, testFiles);
      }
      if (_numTasks == 0) {
        // No outstanding tasks; we're all done.
        // We could later print a summary report here.
      }
    });
    SendPort s = spawnUri(config['pipeline']);

    // Get the names of the source and target test files and containing
    // directories.
    var testPath = new Path(testfile);
    var sourcePath = testPath.directoryPath;
    var sourceDir = sourcePath.toNativePath();

    var targetPath = new Path(config["tempdir"]);
    var normalizedTarget = testPath.directoryPath.toNativePath()
        .replaceAll(Platform.pathSeparator, '_')
        .replaceAll(':', '_');
    targetPath = targetPath.append("${normalizedTarget}_${config['runtime']}");
    var targetDir = targetPath.toNativePath();

    config['targetDir'] = targetDir;
    // If this is a new target dir, we need to redo the pub check.
    var f = null;
    if (targetDir != _testDir) {
      f = doPubConfig(sourcePath, sourceDir, targetPath, targetDir,
          config['pub'], config['runtime']);
      _testDir = targetDir;
    }
    if (f == null) {
      s.send(config, port.toSendPort());
    } else {
      f.then((_) {
        s.send(config, port.toSendPort());
      });
      break; // Don't do any more until pub is done.
    }
  }
}

/**
 * Our tests are configured so that critical messages have a '###' prefix.
 * [writelog] takes the output from a pipeline execution and writes it to
 * our output sinks. It will strip the '###' if necessary on critical
 * messages; other messages will only be written if verbose output was
 * specified.
 */
void writelog(List messages, IOSink out, IOSink log,
              bool includeVerbose, bool skipNonVerbose) {
  for (var i = 0; i < messages.length; i++) {
    var msg = messages[i];
    if (msg.startsWith('###')) {
      if (!skipNonVerbose && out != null) {
        out.write(msg.substring(3));
        out.write('\n');
      }
    } else if (msg.startsWith('CONSOLE MESSAGE:')) {
      if (!skipNonVerbose && out != null) {
        int idx = msg.indexOf('###');
        if (idx > 0) {
          out.write(msg.substring(idx + 3));
          out.write('\n');
        }
      }
    } else if (includeVerbose && log != null) {
      log.write(msg);
      log.write('\n');
    }
  }
}

normalizeFilter(List filter) {
  // We want the filter to be a quoted string or list of quoted
  // strings.
  for (var i = 0; i < filter.length; i++) {
    var f = filter[i];
    if (f[0] != "'" && f[0] != '"') {
      filter[i] = "'$f'"; // TODO(gram): Quote embedded quotes.
    }
  }
  return filter;
}

void sanitizeConfig(Map config, ArgParser parser) {
  config['layout'] = config['layout-text'] || config['layout-pixel'];
  config['verbose'] = (config['log'] != 'none' && !config['list-groups']);
  config['timeout'] = int.parse(config['timeout']);
  config['tasks'] = int.parse(config['tasks']);

  var dartsdk = config['dartsdk'];
  var pathSep = Platform.pathSeparator;

  if (dartsdk == null) {
    var opt = new Options();
    var runner = opt.executable;
    var idx = runner.indexOf('dart-sdk');
    if (idx < 0) {
      print("Please use --dartsdk option or run using the dart executable "
          "from the Dart SDK");
      exit(0);
    }
    dartsdk = runner.substring(0, idx);
  }
  if (Platform.operatingSystem == 'macos') {
    config['dart2js'] =
        '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}dart2js';
    config['dart'] = '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}dart';
    config['pub'] = '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}pub';
    config['drt'] = 
      '$dartsdk/chromium/DumpRenderTree.app/Contents/MacOS/DumpRenderTree';
  } else if (Platform.operatingSystem == 'linux') {
    config['dart2js'] =
        '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}dart2js';
    config['dart'] = '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}dart';
    config['pub'] = '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}pub';
    config['drt'] = '$dartsdk${pathSep}chromium${pathSep}DumpRenderTree';
  } else {
    config['dart2js'] =
        '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}dart2js.bat';
    config['dart'] = '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}dart.exe';
    config['pub'] = '$dartsdk${pathSep}dart-sdk${pathSep}bin${pathSep}pub.bat';
    config['drt'] = '$dartsdk${pathSep}chromium${pathSep}DumpRenderTree.exe';
  }

  for (var prog in [ 'drt', 'dart', 'pub', 'dart2js' ]) {
    config[prog] = makePathAbsolute(config[prog]);
  }
  config['runnerDir'] = runnerDirectory;
  config['include'] = normalizeFilter(config['include']);
  config['exclude'] = normalizeFilter(config['exclude']);
}

main() {
  var optionsParser = getOptionParser();
  var options = loadConfiguration(optionsParser);
  if (isSane(options)) {
    if (options['list-options']) {
      printOptions(optionsParser, options, false, stdout);
    } else if (options['list-all-options']) {
      printOptions(optionsParser, options, true, stdout);
    } else {
      var config = new Map();
      for (var option in options.options) {
        config[option] = options[option];
      }
      var rest = [];
      // Process the remmaining command line args. If they look like
      // options then split them up and add them to the map; they may be for
      // custom pipelines.
      for (var other in options.rest) {
        var idx;
        if (other.startsWith('--') && (idx = other.indexOf('=')) > 0) {
          var optName = other.substring(2, idx);
          var optValue = other.substring(idx+1);
          config[optName] = optValue;
        } else {
          rest.add(other);
        }
      }

      sanitizeConfig(config, optionsParser);

      // Build the list of tests and then execute them.
      List dirs = rest;
      if (dirs.length == 0) {
        dirs.add('.'); // Use current working directory as default.
      }
      var f = buildFileList(dirs,
          new RegExp(config['test-file-pattern']), config['recurse']);
      if (config['sort']) f.sort();
      processTests(config, f);
    }
  }
}
