// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// This library generates Mojo bindings for a Dart package.

library generate;

import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:developer' as dev;
import 'dart:io';

import 'package:mojom/src/utils.dart';
import 'package:path/path.dart' as path;
import 'package:yaml/yaml.dart' as yaml;

part 'mojom_finder.dart';

const String mojoTestPackage = '_mojo_for_test_only';

// A class for running as many generation tasks in parallel as there are cores
// on the machine. Supposing `tasks` is a list of functions of type
// `Future f()`, used as:
//   var runner = new _GenerationTaskRunner(tasks);
//   await runner.run();
// No result is returned.
class _GenerationTaskRunner {
  List<Function> _tasks;
  List<Future> _futures;
  Completer _completer;
  int _numCpus;
  int _nextTaskIndex;
  int _futuresOutstanding;

  _GenerationTaskRunner(this._tasks) {
    _numCpus = Platform.numberOfProcessors;
    _futures = new List<Future>();
    _completer = new Completer();
    _nextTaskIndex = 0;
    _futuresOutstanding = 0;
  }

  Future run() {
    while ((_nextTaskIndex < _numCpus) && (_nextTaskIndex < _tasks.length)) {
      int idx = _nextTaskIndex;
      _futures.add(_tasks[_nextTaskIndex]().then((_) {
        _addNewTask(idx);
      }));
      _nextTaskIndex++;
      _futuresOutstanding++;
    }
    return _completer.future;
  }

  void _addNewTask(int idx) {
    if (_nextTaskIndex < _tasks.length) {
      _futures[idx] = _tasks[_nextTaskIndex]().then((_) {
        _addNewTask(idx);
      });
      _nextTaskIndex++;
    } else {
      _futuresOutstanding--;
      if (_futuresOutstanding == 0) {
        _completer.complete(null);
      }
    }
  }
}

class MojomGenerator {
  static dev.Counter _genMs;
  final bool _errorOnDuplicate;
  final bool _dryRun;
  final bool _force;
  final Directory _mojoSdk;

  Map<String, String> _duplicateDetection;
  int _generationMs;

  MojomGenerator(this._mojoSdk,
      {bool errorOnDuplicate: true, bool profile: false, bool dryRun: false,
       bool force: false})
      : _errorOnDuplicate = errorOnDuplicate,
        _dryRun = dryRun,
        _force = force,
        _generationMs = 0,
        _duplicateDetection = new Map<String, String>() {
    if (_genMs == null) {
      _genMs = new dev.Counter("mojom generation",
          "Time spent waiting for bindings generation script in ms.");
      dev.Metrics.register(_genMs);
    }
  }

  generate(PackageInfo info) async {
    // Count the .mojom files, and find the modification time of the most
    // recently modified one.
    int mojomCount = info.mojomFiles.length;
    DateTime newestMojomTime;
    for (File mojom in info.mojomFiles) {
      DateTime mojomTime = await getModificationTime(mojom);
      if ((newestMojomTime == null) || newestMojomTime.isBefore(mojomTime)) {
        newestMojomTime = mojomTime;
      }
    }

    // Count the .mojom.dart files, and find the modification time of the
    // least recently modified one.
    List mojomDartInfo = await _findOldestMojomDart(info.packageDir);
    DateTime oldestMojomDartTime = null;
    int mojomDartCount = 0;
    if (mojomDartInfo != null) {
      oldestMojomDartTime = mojomDartInfo[0];
      mojomDartCount = mojomDartInfo[1];
    }

    // If we don't have enough .mojom.dart files, or if a .mojom file is
    // newer than the oldest .mojom.dart file, then regenerate.
    if (_force || (mojomDartCount < mojomCount) ||
        _shouldRegenerate(newestMojomTime, oldestMojomDartTime)) {
      var tasks = new List();
      for (File mojom in info.mojomFiles) {
        tasks.add(() => _generateForMojom(
            mojom, info.importDir, info.packageDir, info.name));
      }
      var runner = new _GenerationTaskRunner(tasks);
      await runner.run();

      // Delete any .mojom.dart files that are still older than mojomTime.
      await _deleteOldMojomDart(info.packageDir, newestMojomTime);
    }
  }

  /// Under [package]/lib, returns the oldest modification time for a
  /// .mojom.dart file.
  _findOldestMojomDart(Directory package) async {
    int mojomDartCount = 0;
    DateTime oldestModTime;
    Directory libDir = new Directory(path.join(package.path, 'lib'));
    if (!await libDir.exists()) return null;
    await for (var file in libDir.list(recursive: true, followLinks: false)) {
      if (file is! File) continue;
      if (!isMojomDart(file.path)) continue;
      DateTime modTime = (await file.stat()).modified;
      if ((oldestModTime == null) || oldestModTime.isAfter(modTime)) {
        oldestModTime = modTime;
      }
      mojomDartCount++;
    }
    return [oldestModTime, mojomDartCount];
  }

  // Delete .mojom.dart files under [package] that are [olderThanThis].
  _deleteOldMojomDart(Directory package, DateTime olderThanThis) async {
    Directory libDir = new Directory(path.join(package.path, 'lib'));
    if (!await libDir.exists()) {
      return;
    }
    await for (var file in libDir.list(recursive: true, followLinks: false)) {
      if (file is! File) continue;
      if (!isMojomDart(file.path)) continue;
      DateTime modTime = (await file.stat()).modified;
      if (modTime.isBefore(olderThanThis)) {
        log.warning("Deleting stale .mojom.dart: $file");
        await file.delete();
      }
    }
  }

  /// If the .mojoms file or the newest .mojom is newer than the oldest
  /// .mojom.dart, then regenerate everything.
  bool _shouldRegenerate(DateTime mojomTime, DateTime mojomDartTime) {
    return (mojomTime == null) ||
        (mojomDartTime == null) ||
        mojomTime.isAfter(mojomDartTime);
  }

  _runBindingsGeneration(String script, List<String> arguments) async {
    var result;
    var stopwatch = new Stopwatch()..start();
    result = await Process.run(script, arguments);
    stopwatch.stop();
    _genMs.value += stopwatch.elapsedMilliseconds;
    return result;
  }

  // This is a hack until we can express import paths in .mojom files.
  // This checks the mojom path for '/mojo/services/' and if found assumes
  // this mojom needs //mojo/services as an import path when generating
  // bindings.
  String _sniffForMojoServicesInclude(String mojomPath) {
    List<String> pathComponents = path.split(mojomPath);
    while (pathComponents.length > 2) {
      int last = pathComponents.length;
      if ((pathComponents[last - 1] == 'services') &&
          (pathComponents[last - 2] == 'mojo')) {
        return path.joinAll(pathComponents);
      }
      // Remove the last element and try again.
      pathComponents.removeLast();
    }
    return null;
  }

  _generateForMojom(File mojom, Directory importDir, Directory destination,
      String packageName) async {
    if (!isMojom(mojom.path)) return;
    log.info("_generateForMojom($mojom)");

    final script = path.join(
        _mojoSdk.path, 'tools', 'bindings', 'mojom_bindings_generator.py');
    final sdkInc = path.normalize(path.join(_mojoSdk.path, '..', '..'));
    final outputDir = await Directory.systemTemp.createTemp();
    try {
      final output = outputDir.path;

      final servicesPath = _sniffForMojoServicesInclude(mojom.path);

      // Force type information to be generated for the test package.
      // TODO(afandria): Is there a better way to accomplish this goal?
      // https://github.com/domokit/mojo/issues/641
      final generateTypeInfoFlag = packageName == mojoTestPackage ?
        '--generate-type-info' : '--no-generate-type-info';

      final arguments = [
        '--use_bundled_pylibs',
        '-g',
        'dart',
        '-o',
        output,
        '-I',
        sdkInc,
        '-I',
        importDir.path,
        '--no-gen-imports',
        generateTypeInfoFlag
      ];
      if (servicesPath != null) {
        arguments.add('-I');
        arguments.add(servicesPath);
      }
      arguments.add(mojom.path);

      log.info('Generating $mojom');
      log.info('$script ${arguments.join(" ")}');
      log.info('dryRun = $_dryRun');
      if (!_dryRun) {
        final result = await _runBindingsGeneration(script, arguments);
        if (result.exitCode != 0) {
          log.info("bindings generation result = ${result.exitCode}");
          throw new GenerationError("$script failed:\n"
              "code: ${result.exitCode}\n"
              "stderr: ${result.stderr}\n"
              "stdout: ${result.stdout}");
        } else {
          log.info("bindings generation result = 0");
        }

        // Generated .mojom.dart is under $output/dart-gen/$PACKAGE/lib/$X
        // Move $X to |destination|/lib/$X.
        // Throw an exception if $PACKAGE != [packageName].
        final generatedDirName = path.join(output, 'dart-gen');
        final generatedDir = new Directory(generatedDirName);
        log.info("generatedDir= $generatedDir");
        assert(await generatedDir.exists());
        await for (var genpack in generatedDir.list()) {
          if (genpack is! Directory) continue;
          log.info("genpack = $genpack");
          var libDir = new Directory(path.join(genpack.path, 'lib'));
          var name = path.relative(genpack.path, from: generatedDirName);
          log.info("Found generated lib dir: $libDir");

          if (packageName != name) {
            throw new GenerationError(
                "Tried to generate for package $name in package $packageName");
          }

          var copyDest = new Directory(path.join(destination.path, 'lib'));
          log.info("Copy $libDir to $copyDest");
          await _copyBindings(copyDest, libDir);
        }
      }
    } finally {
      if (await outputDir.exists()) {
        await outputDir.delete(recursive: true);
      }
    }
  }

  /// Searches for .mojom.dart files under [sourceDir] and copies them to
  /// [destDir].
  _copyBindings(Directory destDir, Directory sourceDir) async {
    var sourceList = sourceDir.list(recursive: true, followLinks: false);
    await for (var mojom in sourceList) {
      if (mojom is! File) continue;
      if (!isMojomDart(mojom.path)) continue;
      log.info("Found $mojom");

      final relative = path.relative(mojom.path, from: sourceDir.path);
      final dest = path.join(destDir.path, relative);
      final destDirectory = new Directory(path.dirname(dest));

      if (_errorOnDuplicate && _duplicateDetection.containsKey(dest)) {
        String original = _duplicateDetection[dest];
        throw new GenerationError(
            'Conflict: Both ${original} and ${mojom.path} supply ${dest}');
      }
      _duplicateDetection[dest] = mojom.path;

      log.info('Copying $mojom to $dest');
      if (!_dryRun) {
        final File source = new File(mojom.path);
        final File destFile = new File(dest);
        if (await destFile.exists()) {
          await destFile.delete();
        }
        log.info("Ensuring $destDirectory exists");
        await destDirectory.create(recursive: true);
        await source.copy(dest);
        await markFileReadOnly(dest);
      }
    }
  }
}

/// Given the location of the Mojo SDK and a root directory from which to begin
/// a search. Find .mojom files, and generate bindings for the relevant
/// packages.
class TreeGenerator {
  final MojomGenerator _generator;
  final Directory _mojoSdk;
  final Directory _mojomRootDir;
  final Directory _dartRootDir;
  final List<String> _skip;
  final bool _dryRun;

  Set<String> _processedPackages;

  int errors;

  TreeGenerator(
      Directory mojoSdk, this._mojomRootDir, this._dartRootDir, this._skip,
      {bool dryRun: false, bool force: false})
      : _mojoSdk = mojoSdk,
        _dryRun = dryRun,
        _generator = new MojomGenerator(mojoSdk, dryRun: dryRun, force: force),
        _processedPackages = new Set<String>(),
        errors = 0;

  generate() async {
    var mojomFinder = new MojomFinder(_mojomRootDir, _dartRootDir, _skip);
    List<PackageInfo> packageInfos = await mojomFinder.find();
    for (PackageInfo info in packageInfos) {
      await _runGenerate(info);
    }
  }

  _runGenerate(PackageInfo info) async {
    try {
      log.info('Generating bindings for ${info.name}');
      await _generator.generate(info);
      log.info('Done generating bindings for ${info.name}');
    } on GenerationError catch (e) {
      log.severe('Bindings generation failed for package ${info.name}: $e');
      errors += 1;
    }
  }

  bool _shouldSkip(File f) => containsPrefix(f.path, _skip);
}

/// Given the root of a directory tree to check, and the root of a directory
/// tree containing the canonical generated bindings, checks that the files
/// match, and recommends actions to take in case they don't. The canonical
/// directory should contain a subdirectory for each package that might be
/// encountered while traversing the directory tree being checked.
class TreeChecker {
  final Directory _mojoSdk;
  final Directory _mojomRootDir;
  final Directory _dartRootDir;
  final Directory _canonical;
  final List<String> _skip;
  int _errors;

  TreeChecker(this._mojoSdk, this._mojomRootDir, this._dartRootDir,
      this._canonical, this._skip)
      : _errors = 0;

  check() async {
    // Generate missing .mojoms files if needed.
    var mojomFinder = new MojomFinder(_mojomRootDir, _dartRootDir, _skip);
    List<PackageInfo> packageInfos = await mojomFinder.find();

    for (PackageInfo info in packageInfos) {
      log.info("Checking package at ${info.packageDir}");
      await _checkAll(info.packageDir);
      await _checkSame(info.packageDir);
    }

    // If there were multiple mismatches, explain how to regenerate the bindings
    // for the whole tree.
    if (_errors > 1) {
      String dart = makeRelative(Platform.executable);
      String packRoot = (Platform.packageRoot == "")
          ? ""
          : "-p " + makeRelative(Platform.packageRoot);
      String scriptPath = makeRelative(path.fromUri(Platform.script));
      String mojoSdk = makeRelative(_mojoSdk.path);
      String root = makeRelative(_mojomRootDir.path);
      String dartRoot = makeRelative(_dartRootDir.path);
      String skips = _skip.map((s) => "-s " + makeRelative(s)).join(" ");
      stderr.writeln('It looks like there were multiple problems. '
          'You can run the following command to regenerate bindings for your '
          'whole tree:\n'
          '\t$dart $packRoot $scriptPath gen -m $mojoSdk -r $root -o $dartRoot '
          '$skips');
    }
  }

  int get errors => _errors;

  // Check that the files are the same.
  _checkSame(Directory package) async {
    Directory libDir = new Directory(path.join(package.path, 'lib'));
    await for (var entry in libDir.list(recursive: true, followLinks: false)) {
      if (entry is! File) continue;
      if (!isMojomDart(entry.path)) continue;

      String relPath = path.relative(entry.path, from: package.parent.path);
      File canonicalFile = new File(path.join(_canonical.path, relPath));
      if (!await canonicalFile.exists()) {
        log.info("No canonical file for $entry");
        continue;
      }

      log.info("Comparing $entry with $canonicalFile");
      int fileComparison = await compareFiles(entry, canonicalFile);
      if (fileComparison != 0) {
        String entryPath = makeRelative(entry.path);
        String canonicalPath = makeRelative(canonicalFile.path);
        if (fileComparison > 0) {
          stderr.writeln('The generated file:\n\t$entryPath\n'
              'is newer thanthe canonical file\n\t$canonicalPath\n,'
              'and they are different. Regenerate canonical files?');
        } else {
          String dart = makeRelative(Platform.executable);
          String packRoot = (Platform.packageRoot == "")
              ? ""
              : "-p " + makeRelative(Platform.packageRoot);
          String root = makeRelative(_mojomRootDir.path);
          String packagePath = makeRelative(package.path);
          String scriptPath = makeRelative(path.fromUri(Platform.script));
          String mojoSdk = makeRelative(_mojoSdk.path);
          String skips = _skip.map((s) => "-s " + makeRelative(s)).join(" ");
          stderr.writeln('For the package: $packagePath\n'
              'The generated file:\n\t$entryPath\n'
              'is older than the canonical file:\n\t$canonicalPath\n'
              'and they are different. Regenerate by running:\n'
              '\t$dart $packRoot $scriptPath single -m $mojoSdk -r $root '
              '-p $packagePath $skips');
        }
        _errors++;
        return;
      }
    }
  }

  // Check that every .mojom.dart in the canonical package is also in the
  // package we are checking.
  _checkAll(Directory package) async {
    String packageName = path.relative(package.path, from: package.parent.path);
    String canonicalPackagePath =
        path.join(_canonical.path, packageName, 'lib');
    Directory canonicalPackage = new Directory(canonicalPackagePath);
    if (!await canonicalPackage.exists()) return;

    var canonicalPackages =
        canonicalPackage.list(recursive: true, followLinks: false);
    await for (var entry in canonicalPackages) {
      if (entry is! File) continue;
      if (!isMojomDart(entry.path)) continue;

      String relPath = path.relative(entry.path, from: canonicalPackage.path);
      File genFile = new File(path.join(package.path, 'lib', relPath));
      log.info("Checking that $genFile exists");
      if (!await genFile.exists()) {
        String dart = makeRelative(Platform.executable);
        String packRoot = (Platform.packageRoot == "")
            ? ""
            : "-p " + makeRelative(Platform.packageRoot);
        String root = makeRelative(_mojomRootDir.path);
        String genFilePath = makeRelative(genFile.path);
        String packagePath = makeRelative(package.path);
        String scriptPath = makeRelative(path.fromUri(Platform.script));
        String mojoSdk = makeRelative(_mojoSdk.path);
        String skips = _skip.map((s) => "-s " + makeRelative(s)).join(" ");
        stderr.writeln('The generated file:\n\t$genFilePath\n'
            'is needed but does not exist. Run the command\n'
            '\t$dart $packRoot $scriptPath single -m $mojoSdk -r $root '
            '-p $packagePath $skips');
        _errors++;
        return;
      }
    }
  }

  bool _shouldSkip(File f) => containsPrefix(f.path, _skip);
}
