// 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:json' as json;
import 'dart:utf';

import 'test_runner.dart';
import 'utils.dart' show Path;

/*
 * 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(Command 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.stringify(_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.parse(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(Command 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'],
        encodeUtf8(command_output['stdout']),
        encodeUtf8(command_output['stderr']),
        duration,
        false);
    return commandOutput;
  }

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

