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

import 'dart:io';

import 'package:path/path.dart';

import 'main.dart' as performance;

// Local driver for performance measurement

void main(List<String> args) {
  /*
   * Parse arguments
   */
  if (args.length < 3) printHelp('Expected 3 arguments');
  var gitDir = Directory(args[0]);
  if (!gitDir.existsSync()) printHelp('${gitDir.path} does not exist');
  if (!Directory(join(gitDir.path, '.git')).existsSync()) {
    printHelp('${gitDir.path} does not appear to be a local git repository');
  }
  var branch = args[1];
  var inputFile = File(args[2]);
  if (!inputFile.existsSync()) printHelp('${inputFile.path} does not exist');
  /*
   * Create a new temp directory
   */
  var tmpDir =
      Directory(join(Directory.systemTemp.path, 'analysis_server_perf_target'));
  if (!tmpDir.path.contains('tmp')) throw 'invalid tmp directory\n  $tmpDir';
  print('Extracting target analysis environment into\n  ${tmpDir.path}');
  if (tmpDir.existsSync()) tmpDir.deleteSync(recursive: true);
  tmpDir.createSync(recursive: true);
  /*
   * Setup the initial target source in the temp directory
   */
  var tarFilePath = join(tmpDir.path, 'targetSrc.tar');
  var result = Process.runSync('git', ['archive', branch, '-o', tarFilePath],
      workingDirectory: gitDir.path);
  if (result.exitCode != 0) throw 'failed to obtain target source: $result';
  var tmpSrcDirPath = join(tmpDir.path, 'targetSrc');
  Directory(tmpSrcDirPath).createSync();
  result = Process.runSync('tar', ['-xf', tarFilePath],
      workingDirectory: tmpSrcDirPath);
  if (result.exitCode != 0) throw 'failed to extract target source: $result';
  /*
   * Symlink the out or xcodebuild directory
   */
  var outDirName = 'out';
  if (!Directory(join(gitDir.path, outDirName)).existsSync()) {
    outDirName = 'xcodebuild';
  }
  if (!Directory(join(gitDir.path, outDirName)).existsSync()) {
    throw 'failed to find out or xcodebuild directory';
  }
  result = Process.runSync('ln',
      ['-s', join(gitDir.path, outDirName), join(tmpSrcDirPath, outDirName)]);
  if (result.exitCode != 0) throw 'failed to link out or xcodebuild: $result';
  /*
   * Collect arguments
   */
  var perfArgs = [
    '-i${inputFile.path}',
    '-t$tmpSrcDirPath',
  ];
  for (var index = 3; index < args.length; ++index) {
    perfArgs.add(args[index].replaceAll('@tmpSrcDir@', tmpSrcDirPath));
  }
  perfArgs.add('-m${gitDir.path},$tmpSrcDirPath');
  /*
   * Launch the performance analysis tool
   */
  performance.main(perfArgs);
}

/// Print help and exit
void printHelp([String? errMsg]) {
  if (errMsg != null) {
    print('');
    print('Error: $errMsg');
    print('');
  }
  print('''Required arguments: <gitDir> <branch> <inputFile>
gitDir = a path to the git repository containing the initial target source
branch = the branch containing the initial target source
inputFile = the instrumentation or log file

Optional arguments:''');
  print(performance.argParser.usage);
  exit(1);
}
