// Copyright (c) 2019, 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:convert';
import 'dart:io';
import 'package:compiler/src/commandline_options.dart';

main(List<String> args) async {
  Stopwatch stopwatch = new Stopwatch();
  String input;
  String serializedInput;
  String output = 'out.js';
  List<String> arguments = [];
  int start = 0;
  int stop = 3;
  int shards;
  bool enableAssertions = false;
  for (String arg in args) {
    if (arg.startsWith('-')) {
      if (arg.startsWith('--start=')) {
        start = int.parse(arg.substring('--start='.length));
      } else if (arg.startsWith('--stop=')) {
        stop = int.parse(arg.substring('--stop='.length));
      } else if (arg.startsWith('--shards=')) {
        shards = int.parse(arg.substring('--shards='.length));
      } else if (arg == '-ea' || arg == '--enable_asserts') {
        enableAssertions = true;
      } else if (arg.startsWith('--in=')) {
        serializedInput = arg.substring('--in='.length);
      } else if (arg.startsWith('-o')) {
        output = arg.substring('-o'.length);
      } else if (arg.startsWith('--out=')) {
        output = arg.substring('--out='.length);
      } else {
        arguments.add(arg);
      }
    } else {
      if (input != null) {
        print("Multiple entrypoints provided: '${input}' and '${arg}'.");
        exit(-1);
      }
      input = arg;
    }
  }

  if (input == null) {
    print("No entrypoint provided.");
    exit(-1);
  }

  serializedInput ??= output;

  String inputPrefix = serializedInput;
  if (serializedInput.endsWith('.js')) {
    inputPrefix = output.substring(0, output.length - '.js'.length);
  }
  String outputPrefix = output;
  if (output.endsWith('.js')) {
    outputPrefix = output.substring(0, output.length - '.js'.length);
  }

  List<String> baseOptions = ['--packages=${Platform.packageConfig}'];
  if (enableAssertions) {
    baseOptions.add('--enable_asserts');
  }
  baseOptions.add('package:compiler/src/dart2js.dart');
  baseOptions.addAll(arguments);

  String cfeOutput = '${inputPrefix}0.dill';
  String dillOutput = '${inputPrefix}.dill';
  String dataOutput = '${inputPrefix}.dill.data';
  String codeOutput = '${outputPrefix}.code';
  shards ??= 2;

  stopwatch.start();
  if (start <= 0 && stop >= 0) {
    await subProcess(
        baseOptions, [input, Flags.cfeOnly, '--out=$cfeOutput'], '0:\t');
  }
  if (start <= 1 && stop >= 1) {
    await subProcess(
        baseOptions,
        [cfeOutput, '--out=$dillOutput', '${Flags.writeData}=${dataOutput}'],
        '1:\t');
  }
  if (shards <= 1) {
    await subProcess(
        baseOptions,
        [dillOutput, '${Flags.readData}=${dataOutput}', '--out=${output}'],
        '3:\t');
  } else {
    if (start <= 2 && stop >= 2) {
      List<List<String>> additionalArguments = [];
      List<String> outputPrefixes = [];
      for (int shard = 0; shard < shards; shard++) {
        additionalArguments.add([
          dillOutput,
          '${Flags.readData}=${dataOutput}',
          '${Flags.codegenShard}=$shard',
          '${Flags.codegenShards}=$shards',
          '${Flags.writeCodegen}=${codeOutput}'
        ]);
        outputPrefixes.add('2:${shard + 1}/$shards\t');
      }

      Stopwatch subwatch = new Stopwatch();
      subwatch.start();
      await Future.wait(new List<Future>.generate(shards, (int shard) {
        return subProcess(
            baseOptions, additionalArguments[shard], outputPrefixes[shard]);
      }));
      subwatch.stop();
      print('2:\tTotal time: ${_formatMs(subwatch.elapsedMilliseconds)}');
    }
    if (start <= 3 && stop >= 3) {
      await subProcess(
          baseOptions,
          [
            dillOutput,
            '${Flags.readData}=${dataOutput}',
            '${Flags.readCodegen}=${codeOutput}',
            '${Flags.codegenShards}=$shards',
            '--out=${output}'
          ],
          '3:\t');
    }
  }
  stopwatch.stop();
  print('Total time: ${_formatMs(stopwatch.elapsedMilliseconds)}');
}

Future subProcess(List<String> baseOptions, List<String> additionalOptions,
    String outputPrefix) async {
  List<String> options = []
    ..addAll(baseOptions)
    ..addAll(additionalOptions);
  print(
      '${outputPrefix}Command: ${Platform.resolvedExecutable} ${options.join(' ')}');
  Process process = await Process.start(Platform.resolvedExecutable, options,
      runInShell: true);
  _Prefixer stdoutPrefixer = new _Prefixer(outputPrefix, stdout);
  _Prefixer stderrOutputter = new _Prefixer(outputPrefix, stderr);
  process.stdout.transform(utf8.decoder).listen(stdoutPrefixer);
  process.stderr.transform(utf8.decoder).listen(stderrOutputter);

  int exitCode = await process.exitCode;
  if (exitCode != 0) {
    exit(exitCode);
  }
}

class _Prefixer {
  final String _prefix;
  final Stdout _stdout;
  bool _atNewLine = true;

  _Prefixer(this._prefix, this._stdout);

  void call(String text) {
    int index = 0;
    while (index < text.length) {
      if (_atNewLine) {
        _stdout.write(_prefix);
        _atNewLine = false;
      }
      int pos = text.indexOf('\n', index);
      if (pos != -1) {
        _stdout.write(text.substring(index, pos + 1));
        _atNewLine = true;
        index = pos + 1;
      } else {
        _stdout.write(text.substring(index));
        index = text.length;
      }
    }
  }
}

String _formatMs(int ms) {
  return (ms / 1000).toStringAsFixed(3) + 's';
}
