// Copyright (c) 2016, 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 dart2js.serialization_helper;

import 'dart:async';
import 'dart:io';

import 'package:compiler/compiler_new.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/filenames.dart';

import '../memory_compiler.dart';
import 'test_data.dart';

const String DEFAULT_DATA_FILE_NAME = 'out.data';

class Arguments {
  final String filename;
  final int start;
  final int end;
  final bool loadSerializedData;
  final bool saveSerializedData;
  final String serializedDataFileName;
  final bool verbose;

  const Arguments(
      {this.filename,
      this.start,
      this.end,
      this.loadSerializedData: false,
      this.saveSerializedData: false,
      this.serializedDataFileName: DEFAULT_DATA_FILE_NAME,
      this.verbose: false});

  factory Arguments.from(List<String> arguments) {
    String filename;
    int start;
    int end;
    for (String arg in arguments) {
      if (!arg.startsWith('-')) {
        int index = int.parse(arg, onError: (_) => null);
        if (index == null) {
          filename = arg;
        } else if (start == null) {
          start = index;
        } else {
          end = index;
        }
      }
    }
    bool verbose = arguments.contains('-v');
    bool loadSerializedData = arguments.contains('-l');
    bool saveSerializedData = arguments.contains('-s');
    if (arguments.contains('--auto')) {
      File file = new File(DEFAULT_DATA_FILE_NAME);
      if (file.existsSync()) {
        loadSerializedData = true;
      } else {
        saveSerializedData = true;
      }
    }
    return new Arguments(
        filename: filename,
        start: start,
        end: end,
        verbose: verbose,
        loadSerializedData: loadSerializedData,
        saveSerializedData: saveSerializedData);
  }

  Uri get uri {
    if (filename != null) {
      return Uri.base.resolve(nativeToUriPath(filename));
    }
    return null;
  }

  Future forEachTest(SerializedData serializedData, List<Test> tests,
      TestFunction testFunction) async {
    Uri entryPoint = Uri.parse('memory:main.dart');
    int first = start ?? 0;
    int last = end ?? tests.length;

    for (int index = first; index < last; index++) {
      Test test = TESTS[index];
      List<SerializedData> dataList =
          await preserializeData(serializedData, test);
      Map<String, String> sourceFiles = <String, String>{};
      sourceFiles.addAll(test.sourceFiles);
      if (test.preserializedSourceFiles != null) {
        sourceFiles.addAll(test.preserializedSourceFiles);
      }
      if (test.unserializedSourceFiles != null) {
        sourceFiles.addAll(test.unserializedSourceFiles);
      }
      List<Uri> resolutionInputs = <Uri>[];
      for (SerializedData data in dataList) {
        data.expandMemorySourceFiles(sourceFiles);
        data.expandUris(resolutionInputs);
      }
      await testFunction(entryPoint,
          sourceFiles: sourceFiles,
          resolutionInputs: resolutionInputs,
          index: index,
          test: test,
          verbose: verbose);
    }
  }
}

typedef Future TestFunction(Uri entryPoint,
    {Map<String, String> sourceFiles,
    List<Uri> resolutionInputs,
    int index,
    Test test,
    bool verbose});

Future<SerializedData> serializeDartCore(
    {Arguments arguments: const Arguments()}) {
  return measure('dart:core', 'serialize', () async {
    Uri uri = Uri.parse('memory:${arguments.serializedDataFileName}');
    SerializedData serializedData;
    if (arguments.loadSerializedData) {
      File file = new File(arguments.serializedDataFileName);
      if (file.existsSync()) {
        print('Loading data from $file');
        serializedData = new SerializedData(uri, file.readAsStringSync());
      }
    } else {
      SerializationResult result =
          await serialize(Uris.dart_core, dataUri: uri);
      serializedData = result.serializedData;
    }
    if (arguments.saveSerializedData) {
      File file = new File(arguments.serializedDataFileName);
      print('Saving data to $file');
      file.writeAsStringSync(serializedData.data);
    }
    return serializedData;
  });
}

class SerializationResult {
  final Compiler compiler;
  final SerializedData serializedData;

  SerializationResult(this.compiler, this.serializedData);
}

Future<SerializationResult> serialize(Uri entryPoint,
    {Map<String, String> memorySourceFiles: const <String, String>{},
    List<Uri> resolutionInputs: const <Uri>[],
    Uri dataUri,
    bool deserializeCompilationDataForTesting: false}) async {
  if (dataUri == null) {
    dataUri = Uri.parse('memory:${DEFAULT_DATA_FILE_NAME}');
  }
  OutputCollector outputCollector = new OutputCollector();
  Compiler compiler = compilerFor(
      options: [Flags.resolveOnly, Flags.useOldFrontend],
      memorySourceFiles: memorySourceFiles,
      resolutionInputs: resolutionInputs,
      outputProvider: outputCollector);
  compiler.serialization.deserializeCompilationDataForTesting =
      deserializeCompilationDataForTesting;
  await compiler.run(entryPoint);
  SerializedData serializedData = new SerializedData(
      dataUri, outputCollector.getOutput('', OutputType.serializationData));
  return new SerializationResult(compiler, serializedData);
}

class SerializedData {
  final Uri uri;
  final String data;

  SerializedData(this.uri, this.data) {
    assert(uri != null);
    assert(data != null);
  }

  Map<String, String> toMemorySourceFiles([Map<String, String> input]) {
    Map<String, String> sourceFiles = <String, String>{};
    if (input != null) {
      sourceFiles.addAll(input);
    }
    expandMemorySourceFiles(sourceFiles);
    return sourceFiles;
  }

  void expandMemorySourceFiles(Map<String, String> sourceFiles) {
    if (uri.scheme == 'memory') {
      sourceFiles[uri.path] = data;
    }
  }

  List<Uri> toUris([List<Uri> input]) {
    List<Uri> uris = <Uri>[];
    if (input != null) {
      uris.addAll(input);
    }
    expandUris(uris);
    return uris;
  }

  void expandUris(List<Uri> uris) {
    uris.add(uri);
  }
}

Future<List<SerializedData>> preserializeData(
    SerializedData serializedData, Test test) async {
  if (test == null ||
      test.preserializedSourceFiles == null ||
      test.preserializedSourceFiles.isEmpty) {
    return <SerializedData>[serializedData];
  }

  List<Uri> uriList = <Uri>[];
  for (String key in test.preserializedSourceFiles.keys) {
    uriList.add(Uri.parse('memory:$key'));
  }
  Map<String, String> sourceFiles = serializedData.toMemorySourceFiles();
  sourceFiles.addAll(test.preserializedSourceFiles);
  if (test.unserializedSourceFiles != null) {
    sourceFiles.addAll(test.unserializedSourceFiles);
  }
  Uri additionalDataUri = Uri.parse('memory:additional.data');
  SerializedData additionalSerializedData;
  if (test.sourceFiles.isEmpty) {
    SerializationResult result = await serialize(uriList.first,
        memorySourceFiles: sourceFiles,
        resolutionInputs: serializedData.toUris(),
        dataUri: additionalDataUri);
    additionalSerializedData = result.serializedData;
  } else {
    OutputCollector outputCollector = new OutputCollector();
    Compiler compiler = compilerFor(
        entryPoint: test.sourceFiles.isEmpty ? uriList.first : null,
        memorySourceFiles: sourceFiles,
        resolutionInputs: serializedData.toUris(),
        options: [Flags.resolveOnly, Flags.useOldFrontend],
        outputProvider: outputCollector);
    compiler.librariesToAnalyzeWhenRun = uriList;
    await compiler.run(null);
    List<LibraryElement> libraries = <LibraryElement>[];
    for (Uri uri in uriList) {
      libraries.add(compiler.libraryLoader.lookupLibrary(uri));
    }
    additionalSerializedData = new SerializedData(additionalDataUri,
        outputCollector.getOutput('', OutputType.serializationData));
  }
  return <SerializedData>[serializedData, additionalSerializedData];
}

class MeasurementResult {
  final String title;
  final String taskTitle;
  final int elapsedMilliseconds;

  MeasurementResult(this.title, this.taskTitle, this.elapsedMilliseconds);
}

final List<MeasurementResult> measurementResults = <MeasurementResult>[];

/// Print all store [measurementResults] grouped by title and sorted by
/// decreasing execution time.
void printMeasurementResults() {
  Map<String, int> totals = <String, int>{};

  for (MeasurementResult result in measurementResults) {
    totals.putIfAbsent(result.title, () => 0);
    totals[result.title] += result.elapsedMilliseconds;
  }

  List<String> sorted = totals.keys.toList();
  sorted.sort((a, b) => -totals[a].compareTo(totals[b]));

  int paddingLength = '${totals[sorted.first]}'.length;

  String pad(int value) {
    String text = '$value';
    return '${' ' * (paddingLength - text.length)}$text';
  }

  print('================================================================');
  print('Summary:');
  for (String task in sorted) {
    int time = totals[task];
    print('${pad(time)}ms $task');
  }

  measurementResults.clear();
}

/// Measure execution of [task], print the result and store it in
/// [measurementResults] for a summary.
Future measure(String title, String taskTitle, Future task()) async {
  Stopwatch stopwatch = new Stopwatch()..start();
  print('================================================================');
  print('$taskTitle: $title');
  print('----------------------------------------------------------------');
  var result = await task();
  stopwatch.stop();
  int elapsedMilliseconds = stopwatch.elapsedMilliseconds;
  print('$taskTitle: $title: ${elapsedMilliseconds}ms');
  measurementResults
      .add(new MeasurementResult(title, taskTitle, elapsedMilliseconds));
  return result;
}
