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

part of debugger;

class DebuggerLocation {
  DebuggerLocation.file(this.script, this.line, this.col);
  DebuggerLocation.func(this.function);
  DebuggerLocation.error(this.errorMessage);

  static RegExp sourceLocMatcher = new RegExp(r'^([^\d:][^:]+:)?(\d+)(:\d+)?');
  static RegExp functionMatcher = new RegExp(r'^([^.]+)([.][^.]+)?');

  /// Parses a source location description.
  ///
  /// Formats:
  ///   ''                -  current position
  ///   13                -  line 13, current script
  ///   13:20             -  line 13, col 20, current script
  ///   script.dart:13    -  line 13, script.dart
  ///   script.dart:13:20 -  line 13, col 20, script.dart
  ///   main              -  function
  ///   FormatException   -  constructor
  ///   _SHA1._updateHash -  method
  static Future<DebuggerLocation> parse(Debugger debugger, String locDesc) {
    if (locDesc == '') {
      // Special case: '' means return current location.
      return _currentLocation(debugger);
    }

    // Parse the location description.
    var match = sourceLocMatcher.firstMatch(locDesc);
    if (match != null) {
      return _parseScriptLine(debugger, match);
    }
    match = functionMatcher.firstMatch(locDesc);
    if (match != null) {
      return _parseFunction(debugger, match);
    }
    return new Future.value(new DebuggerLocation.error(
        "Invalid source location '${locDesc}'"));
  }

  static Future<Frame> _currentFrame(Debugger debugger) async {
    ServiceMap stack = debugger.stack;
    if (stack == null || stack['frames'].length == 0) {
      return null;
    }
    return stack['frames'][debugger.currentFrame];
  }

  static Future<DebuggerLocation> _currentLocation(Debugger debugger) async {
    var frame = await _currentFrame(debugger);
    if (frame == null) {
      return new DebuggerLocation.error(
          'A script must be provided when the stack is empty');
    }
    Script script = frame.location.script;
    await script.load();
    var line = script.tokenToLine(frame.location.tokenPos);
    var col = script.tokenToCol(frame.location.tokenPos);
    return new DebuggerLocation.file(script, line, col);
  }

  static Future<DebuggerLocation> _parseScriptLine(Debugger debugger,
                                                   Match match) async {
    var scriptName = match.group(1);
    if (scriptName != null) {
      scriptName = scriptName.substring(0, scriptName.length - 1);
    }
    var lineStr = match.group(2);
    assert(lineStr != null);
    var colStr = match.group(3);
    if (colStr != null) {
      colStr = colStr.substring(1);
    }
    var line = int.parse(lineStr, onError:(_) => -1);
    var col = (colStr != null
               ? int.parse(colStr, onError:(_) => -1)
               : null);
    if (line == -1) {
      return new Future.value(new DebuggerLocation.error(
          "Line '${lineStr}' must be an integer"));
    }
    if (col == -1) {
      return new Future.value(new DebuggerLocation.error(
          "Column '${colStr}' must be an integer"));
    }

    if (scriptName != null) {
      // Resolve the script.
      var scripts = await _lookupScript(debugger.isolate, scriptName);
      if (scripts.length == 0) {
        return new DebuggerLocation.error("Script '${scriptName}' not found");
      } else if (scripts.length == 1) {
        return new DebuggerLocation.file(scripts[0], line, col);
      } else {
        // TODO(turnidge): Allow the user to disambiguate.
        return
            new DebuggerLocation.error("Script '${scriptName}' is ambiguous");
      }
    } else {
      // No script provided.  Default to top of stack for now.
      var frame = await _currentFrame(debugger);
      if (frame == null) {
        return new Future.value(new DebuggerLocation.error(
            'A script must be provided when the stack is empty'));
      }
      Script script = frame.location.script;
      await script.load();
      return new DebuggerLocation.file(script, line, col);
    }
  }

  static Future<List<Script>> _lookupScript(Isolate isolate,
                                            String name,
                                            {bool allowPrefix: false}) {
    var pending = [];
    for (var lib in isolate.libraries) {
      if (!lib.loaded) {
        pending.add(lib.load());
      }
    }
    return Future.wait(pending).then((_) {
      List matches = [];
      for (var lib in isolate.libraries) {
        for (var script in lib.scripts) {
          if (allowPrefix) {
            if (script.name.startsWith(name)) {
              matches.add(script);
            }
          } else {
            if (name == script.name) {
              matches.add(script);
            }
          }
        }
      }
      return matches;
    });
  }

  static List<ServiceFunction> _lookupFunction(Isolate isolate,
                                               String name,
                                               { bool allowPrefix: false }) {
    var matches = [];
    for (var lib in isolate.libraries) {
      assert(lib.loaded);
      for (var function in lib.functions) {
        if (allowPrefix) {
          if (function.name.startsWith(name)) {
            matches.add(function);
          }
        } else {
          if (name == function.name) {
            matches.add(function);
          }
        }
      }
    }
    return matches;
  }

  static Future<List<Class>> _lookupClass(Isolate isolate,
                                          String name,
                                          { bool allowPrefix: false }) async {
    if (isolate == null) {
      return [];
    }
    var pending = [];
    for (var lib in isolate.libraries) {
      assert(lib.loaded);
      for (var cls in lib.classes) {
        if (!cls.loaded) {
          pending.add(cls.load());
        }
      }
    }
    await Future.wait(pending);
    var matches = [];
    for (var lib in isolate.libraries) {
      for (var cls in lib.classes) {
        if (allowPrefix) {
          if (cls.name.startsWith(name)) {
            matches.add(cls);
          }
        } else {
          if (name == cls.name) {
            matches.add(cls);
          }
        }
      }
    }
    return matches;
  }

  static ServiceFunction _getConstructor(Class cls, String name) {
    for (var function in cls.functions) {
      assert(cls.loaded);
      if (name == function.name) {
        return function;
      }
    }
    return null;
  }

  // TODO(turnidge): This does not handle named functions which are
  // inside of named functions, e.g. foo.bar.baz.
  static Future<DebuggerLocation> _parseFunction(Debugger debugger,
                                               Match match) {
    Isolate isolate = debugger.isolate;
    var base = match.group(1);
    var qualifier = match.group(2);
    assert(base != null);

    return _lookupClass(isolate, base).then((classes) {
      var functions = [];
      if (qualifier == null) {
        // Unqualified name is either a function or a constructor.
        functions.addAll(_lookupFunction(isolate, base));

        for (var cls in classes) {
          // Look for a self-named constructor.
          var constructor = _getConstructor(cls, cls.name);
          if (constructor != null) {
            functions.add(constructor);
          }
        }
      } else {
        // Qualified name.
        var functionName = qualifier.substring(1);
        for (var cls in classes) {
          assert(cls.loaded);
          for (var function in cls.functions) {
            if (function.kind == FunctionKind.kConstructor) {
              // Constructor names are class-qualified.
              if (match.group(0) == function.name) {
                functions.add(function);
              }
            } else {
              if (functionName == function.name) {
                functions.add(function);
              }
            }
          }
        }
      }
      if (functions.length == 0) {
        return new DebuggerLocation.error(
            "Function '${match.group(0)}' not found");
      } else if (functions.length == 1) {
        return new DebuggerLocation.func(functions[0]);
      } else {
        // TODO(turnidge): Allow the user to disambiguate.
        return new DebuggerLocation.error(
            "Function '${match.group(0)}' is ambiguous");
      }
      return new DebuggerLocation.error('foo');
    });
  }

  static RegExp partialSourceLocMatcher =
      new RegExp(r'^([^\d:]?[^:]+[:]?)?(\d+)?([:]\d*)?');
  static RegExp partialFunctionMatcher = new RegExp(r'^([^.]*)([.][^.]*)?');

  /// Completes a partial source location description.
  static Future<List<String>> complete(Debugger debugger, String locDesc) {
    List<Future<List<String>>> pending = [];
    var match = partialFunctionMatcher.firstMatch(locDesc);
    if (match != null) {
      pending.add(_completeFunction(debugger, match));
    }

    match = partialSourceLocMatcher.firstMatch(locDesc);
    if (match != null) {
      pending.add(_completeFile(debugger, match));
    }

    return Future.wait(pending).then((List<List<String>> responses) {
      var completions = [];
      for (var response in responses) {
        completions.addAll(response);
      }
      return completions;
    });
  }

  static Future<List<String>> _completeFunction(Debugger debugger,
                                                Match match) {
    Isolate isolate = debugger.isolate;
    var base = match.group(1);
    var qualifier = match.group(2);
    base = (base == null ? '' : base);

    if (qualifier == null) {
      return _lookupClass(isolate, base, allowPrefix:true).then((classes) {
        var completions = [];

        // Complete top-level function names.
        var functions = _lookupFunction(isolate, base, allowPrefix:true);
        var funcNames = functions.map((f) => f.name).toList();
        funcNames.sort();
        completions.addAll(funcNames);

        // Complete class names.
        var classNames = classes.map((f) => f.name).toList();
        classNames.sort();
        completions.addAll(classNames);

        return completions;
      });
    } else {
      return _lookupClass(isolate, base, allowPrefix:false).then((classes) {
        var completions = [];
        for (var cls in classes) {
          for (var function in cls.functions) {
            if (function.kind == FunctionKind.kConstructor) {
              if (function.name.startsWith(match.group(0))) {
                completions.add(function.name);
              }
            } else {
              if (function.qualifiedName.startsWith(match.group(0))) {
                completions.add(function.qualifiedName);
              }
            }
          }
        }
        completions.sort();
        return completions;
      });
    }
  }

  static bool _startsWithDigit(String s) {
    return '0'.compareTo(s[0]) <= 0 && '9'.compareTo(s[0]) >= 0;
  }

  static Future<List<String>> _completeFile(
      Debugger debugger, Match match) async {
    var scriptName;
    var scriptNameComplete = false;
    var lineStr;
    var lineStrComplete = false;
    var colStr;
    if (_startsWithDigit(match.group(1))) {
      // CASE 1: We have matched a prefix of (lineStr:)(colStr)
      var frame = await _currentFrame(debugger);
      if (frame == null) {
        return [];
      }
      scriptName = frame.location.script.name;
      scriptNameComplete = true;
      lineStr = match.group(1);
      lineStr = (lineStr == null ? '' : lineStr);
      if (lineStr.endsWith(':')) {
        lineStr = lineStr.substring(0, lineStr.length - 1);
        lineStrComplete = true;
      }
      colStr = match.group(2);
      colStr = (colStr == null ? '' : colStr);
    } else {
      // CASE 2: We have matched a prefix of (scriptName:)(lineStr)(:colStr)
      scriptName = match.group(1);
      scriptName = (scriptName == null ? '' : scriptName);
      if (scriptName.endsWith(':')) {
        scriptName = scriptName.substring(0, scriptName.length - 1);
        scriptNameComplete = true;
      }
      lineStr = match.group(2);
      lineStr = (lineStr == null ? '' : lineStr);
      colStr = match.group(3);
      colStr = (colStr == null ? '' : colStr);
      if (colStr.startsWith(':')) {
        lineStrComplete = true;
        colStr = colStr.substring(1);
      }
    }

    if (!scriptNameComplete) {
      // The script name is incomplete.  Complete it.
      var scripts =
          await _lookupScript(debugger.isolate, scriptName, allowPrefix:true);
      List completions = [];
      for (var script in scripts) {
        completions.add(script.name + ':');
      }
      completions.sort();
      return completions;

    } else {
      // The script name is complete.  Look it up.
      var scripts =
          await _lookupScript(debugger.isolate, scriptName, allowPrefix:false);
      if (scripts.isEmpty) {
        return [];
      }
      var script = scripts[0];
      await script.load();
      if (!lineStrComplete) {
        // Complete the line.
        var sharedPrefix = '${script.name}:';
        List completions = [];
        var report = await script.isolate.getSourceReport(
            [Isolate.kPossibleBreakpointsReport], script);
        Set<int> possibleBpts = getPossibleBreakpointLines(report, script);
        for (var line in possibleBpts) {
          var currentLineStr = line.toString();
          if (currentLineStr.startsWith(lineStr)) {
            completions.add('${sharedPrefix}${currentLineStr} ');
            completions.add('${sharedPrefix}${currentLineStr}:');
          }
        }
        return completions;

      } else {
        // Complete the column.
        int lineNum = int.parse(lineStr);
        var scriptLine = script.getLine(lineNum);
        var sharedPrefix = '${script.name}:${lineStr}:';
        List completions = [];
        int maxCol = scriptLine.text.trimRight().runes.length;
        for (int i = 1; i <= maxCol; i++) {
          var currentColStr = i.toString();
          if (currentColStr.startsWith(colStr)) {
            completions.add('${sharedPrefix}${currentColStr} ');
          }
        }
        return completions;
      }
    }
  }

  String toString() {
    if (valid) {
      if (function != null) {
        return '${function.qualifiedName}';
      } else if (col != null) {
        return '${script.name}:${line}:${col}';
      } else {
        return '${script.name}:${line}';
      }
    }
    return 'invalid source location (${errorMessage})';
  }

  Script script;
  int line;
  int col;
  ServiceFunction function;
  String errorMessage;
  bool get valid => (errorMessage == null);
}
