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

/// Command-line tool to query for code dependencies. Currently this tool only
/// supports the `some_path` query, which gives you the shortest path for how
/// one function depends on another.
///
/// You can run this tool as follows:
/// ```bash
/// pub global activate dart2js_info
/// dart2js_info_code_deps out.js.info.json some_path main foo
/// ```
///
/// The arguments to the query are regular expressions that can be used to
/// select a single element in your program. If your regular expression is too
/// general and has more than one match, this tool will pick
/// the first match and ignore the rest. Regular expressions are matched against
/// a fully qualified element name, which includes the library and class name
/// (if any) that contains it. A typical qualified name is of this form:
///
///     libraryName::ClassName.elementName
///
/// If the name of a function your are looking for is unique enough, it might be
/// sufficient to just write that name as your regular expression.
library dart2js_info.bin.code_deps;

import 'dart:collection';
import 'dart:io';

import 'package:dart2js_info/info.dart';
import 'package:dart2js_info/src/graph.dart';
import 'package:dart2js_info/src/util.dart';

main(args) async {
  if (args.length < 2) {
    print('usage: dart2js_info_code_deps path-to.info.json <query>');
    print('   where <query> can be:');
    print('     - some_path <element-regexp-1> <element-regexp-2>');
    // TODO(sigmund): add other queries, such as 'all_paths'.
    exit(1);
  }

  var info = await infoFromFile(args.first);
  var graph = graphFromInfo(info);

  var queryName = args[1];
  if (queryName == 'some_path') {
    if (args.length < 4) {
      print('missing arguments for `some_path`');
      exit(1);
    }
    var source = info.functions
        .firstWhere(_longNameMatcher(new RegExp(args[2])), orElse: () => null);
    var target = info.functions
        .firstWhere(_longNameMatcher(new RegExp(args[3])), orElse: () => null);
    print('query: some_path');
    if (source == null) {
      print("source '${args[2]}' not found in '${args[0]}'");
      exit(1);
    }
    print('source: ${longName(source)}');
    if (target == null) {
      print("target '${args[3]}' not found in '${args[0]}'");
      exit(1);
    }
    print('target: ${longName(target)}');
    var path = new SomePathQuery(source, target).run(graph);
    if (path.isEmpty) {
      print('result: no path found');
    } else {
      print('result:');
      for (int i = 0; i < path.length; i++) {
        print('  $i. ${longName(path[i])}');
      }
    }
  } else {
    print('unrecognized query: $queryName');
  }
}

/// A query supported by this tool.
abstract class Query {
  run(Graph<Info> graph);
}

/// Query that searches for a single path between two elements.
class SomePathQuery {
  /// The info associated with the source element.
  Info source;

  /// The info associated with the target element.
  Info target;

  SomePathQuery(this.source, this.target);

  List<Info> run(Graph<Info> graph) {
    var seen = {source: null};
    var queue = new Queue<Info>();
    queue.addLast(source);
    while (queue.isNotEmpty) {
      var node = queue.removeFirst();
      if (identical(node, target)) {
        var result = new Queue<Info>();
        while (node != null) {
          result.addFirst(node);
          node = seen[node];
        }
        return result.toList();
      }
      for (var neighbor in graph.targetsOf(node)) {
        if (seen.containsKey(neighbor)) continue;
        seen[neighbor] = node;
        queue.addLast(neighbor);
      }
    }
    return [];
  }
}

typedef bool LongNameMatcher(FunctionInfo info);

LongNameMatcher _longNameMatcher(RegExp regexp) =>
    (e) => regexp.hasMatch(longName(e));
