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

part of generate;

class PackageInfo {
  final String name;
  final Directory packageDir;
  final Directory importDir;
  final List<File> mojomFiles;
  PackageInfo(this.name, this.packageDir, this.importDir, this.mojomFiles);
}

/// This class finds .mojom files under [_mojomRootDir] that have a
/// 'DartPackage' annotation. It locates the packages named in the annotations
/// and generates a list of [PackageInfo] records.
class MojomFinder {
  static final Stopwatch _stopwatch = new Stopwatch();
  static dev.Counter _mojomMs;

  Directory _mojomRootDir;
  Directory _dartRootDir;
  List<String> _skip;

  // Cache of mappings from package name to Dart source location.
  HashMap<String, Directory> _packageLocations;

  MojomFinder(this._mojomRootDir, this._dartRootDir, this._skip) {
    _packageLocations = new HashMap<String, Directory>();
    if (_mojomMs == null) {
      _mojomMs = new dev.Counter("mojom searching",
          "Time(ms) searching for .mojom files with DartPackage annotations.");
      dev.Metrics.register(_mojomMs);
    }
  }

  /// Look for .mojom files in the tree that have a DartPackage annotation.
  /// Return a list of PackageInfo records describing packages and the .mojom
  /// files that they own.
  Future<List<PackageInfo>> find() async {
    _stopwatch.start();
    var packageInfos = new Map<String, PackageInfo>();
    var mojomRootList = _mojomRootDir.list(recursive: true, followLinks: false);
    await for (var entry in mojomRootList) {
      if (entry is! File) continue;
      if (_shouldSkip(entry)) continue;
      if (!isMojom(entry.path)) continue;

      String package = await _extractDartPackageAttribute(entry);
      if (package == null) continue;

      log.info("MojomFinder: found package $package");
      if (packageInfos.containsKey(package)) {
        packageInfos[package].mojomFiles.add(entry);
        continue;
      }

      Directory dartSourceDir = await _findDartSourceDir(package);
      if (dartSourceDir == null) {
        log.warning(".mojom had annotation '$package', but no package by that "
            "name under $_dartRootDir could be found.");
        continue;
      }
      log.info("MojomFinder: found $package at $dartSourceDir");

      var packageInfo =
          new PackageInfo(package, dartSourceDir, _mojomRootDir, [entry]);
      packageInfos[package] = packageInfo;
    }
    _stopwatch.stop();
    _mojomMs.value += _stopwatch.elapsedMilliseconds;
    _stopwatch.reset();
    return packageInfos.values.toList();
  }

  // Extract a DartPackage attribute from a .mojom file.
  Future<String> _extractDartPackageAttribute(File mojom) async {
    String contents = await mojom.readAsString();
    int dpIndex = contents.indexOf('DartPackage');
    if (dpIndex == -1) return null;

    // There must be a '[' before 'DartPackage', and there can't be a ']'
    // in between.
    int openSbIndex = contents.lastIndexOf('[', dpIndex);
    if (openSbIndex == -1) return null;
    int closeSbIndex = contents.lastIndexOf(']', dpIndex);
    if (closeSbIndex > openSbIndex) return null;

    int eqIndex = contents.indexOf('=', dpIndex);
    if (eqIndex == -1) return null;
    int openQuoteIndex = contents.indexOf('"', eqIndex);
    if (openQuoteIndex == -1) return null;
    int closeQuoteIndex = -1;
    int searchIndex = openQuoteIndex + 1;
    while (closeQuoteIndex == -1) {
      closeQuoteIndex = contents.indexOf('"', searchIndex);
      if (closeQuoteIndex == -1) break;
      if (contents[closeQuoteIndex - 1] == '\\') {
        searchIndex = closeQuoteIndex + 1;
        closeQuoteIndex = -1;
      }
    }
    if (closeQuoteIndex == -1) return null;
    return contents.substring(openQuoteIndex + 1, closeQuoteIndex);
  }

  // Finds where the Dart package named [package] lives. Looks immediately
  // under [_dartRootDir].
  Future<Directory> _findDartSourceDir(String package) async {
    if (_packageLocations.containsKey(package)) {
      return _packageLocations[package];
    }
    var packagePath = path.join(_dartRootDir.path, package);
    Directory packageDir = new Directory(packagePath);
    if (await packageDir.exists()) {
      log.info("Found dart package $package at $packagePath");
      _packageLocations[package] = packageDir;
      return packageDir;
    }

    // If the directory doesn't exist, look for a pubspec.yaml file with a
    // 'name:' field matching the package name.
    Directory dir = await _findDartSourceDirByPubspec(package);
    if (dir != null) {
      _packageLocations[package] = dir;
      return dir;
    } else {
      log.info("$packagePath not found");
      return null;
    }
  }

  Future<Directory> _findDartSourceDirByPubspec(String package) async {
    await for (var entry in _dartRootDir.list(recursive: true)) {
      if (entry is! File) continue;
      if (_shouldSkip(entry)) continue;
      if (!isPubspecYaml(entry.path)) continue;
      String contents = await entry.readAsString();
      var pubspec = yaml.loadYaml(contents);
      String name = pubspec['name'];
      if (name == package) {
        log.info("Found dart package $package at ${entry.parent}");
        return entry.parent;
      }
    }
    return null;
  }

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