// 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.

library record_and_replay;

import 'dart:io';
import 'dart:convert';

import 'path.dart';
import 'test_runner.dart';

/*
 * Json files look like this:
 *
 * [
 *   {
 *     'name' : '...',
 *     'command' : {
 *       'timeout_limit' : 60,
 *       'executable' : '...',
 *       'arguments' : ['arg1, 'arg2', '...'],
 *     },
 *     'command_output' : {
 *       'exit_code' : 42,
 *       'stdout' : '...',
 *       'stderr' : '...',
 *       'duration' : 1.5,
 *       'did_timeout' : false,
 *     },
 *   },
 *   ....
 * ]
 */

List<String> makePathsRelativeToDart(String cwd, List<String> arguments) {
  var relativeArguments = [];
  for (var rawArgument in arguments) {
    if (rawArgument.startsWith(cwd)) {
      var relative = new Path(rawArgument).relativeTo(new Path(cwd));
      relativeArguments.add(relative.toNativePath());
    } else {
      relativeArguments.add(rawArgument);
    }
  }
  return relativeArguments;
}

class TestCaseRecorder {
  Path _outputPath;
  List<Map> _recordedCommandInvocations = [];
  var _cwd;

  TestCaseRecorder(this._outputPath) {
    _cwd = Directory.current.path;
  }

  void nextCommand(ProcessCommand command, int timeout) {
    // Convert arguments from absolute to relative paths (relative to the dart
    // directory) because the absolute path on the machine where we record
    // may be different from the absolute path on the machine where we execute
    // the commands.
    var arguments = makePathsRelativeToDart(_cwd, command.arguments);

    var commandExecution = {
      'name': command.displayName,
      'command': {
        'timeout_limit': timeout,
        'executable': command.executable,
        'arguments': arguments,
      },
    };
    _recordedCommandInvocations.add(commandExecution);
  }

  void finish() {
    var file = new File(_outputPath.toNativePath());
    var jsonString = JSON.encode(_recordedCommandInvocations);
    file.writeAsStringSync(jsonString);
    print("TestCaseRecorder: written all TestCases to ${_outputPath}");
  }
}

class TestCaseOutputArchive {
  Map<String, Map> _commandOutputRecordings;
  var _cwd;

  TestCaseOutputArchive() {
    _cwd = Directory.current.path;
  }

  void loadFromPath(Path recordingPath) {
    var file = new File(recordingPath.toNativePath());
    var commandRecordings = JSON.decode(file.readAsStringSync());
    _commandOutputRecordings = {};
    for (var commandRecording in commandRecordings) {
      var key = _indexKey(commandRecording['command']['executable'],
          commandRecording['command']['arguments'].join(' '));
      _commandOutputRecordings[key] = commandRecording['command_output'];
    }
  }

  CommandOutput outputOf(ProcessCommand command) {
    // Convert arguments from absolute to relative paths (relative to the dart
    // directory) because the absolute path on the machine where we record
    // may be different from the absolute path on the machine where we execute
    // the commands.
    var arguments = makePathsRelativeToDart(_cwd, command.arguments);

    var key = _indexKey(command.executable, arguments.join(' '));
    var command_output = _commandOutputRecordings[key];
    if (command_output == null) {
      print("Sorry, but there is no command output for ${command.displayName}"
          " ($command)");
      exit(42);
    }

    double seconds = command_output['duration'];
    var duration = new Duration(
        seconds: seconds.round(), milliseconds: (seconds / 1000).round());
    var commandOutput = createCommandOutput(
        command,
        command_output['exit_code'],
        command_output['did_timeout'],
        UTF8.encode(command_output['stdout']),
        UTF8.encode(command_output['stderr']),
        duration,
        false);
    return commandOutput;
  }

  String _indexKey(String executable, String arguments) {
    return "${executable}__$arguments";
  }
}
