// 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 SourceLocation {
  SourceLocation.file(this.script, this.line, this.col);
  SourceLocation.func(this.function);
  SourceLocation.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<SourceLocation> 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 SourceLocation.error(
        "Invalid source location '${locDesc}'"));
  }

  static Future<SourceLocation> _currentLocation(Debugger debugger) {
    ServiceMap stack = debugger.stack;
    if (stack == null || stack['frames'].length == 0) {
      return new Future.value(new SourceLocation.error(
          'A script must be provided when the stack is empty'));
    }
    var frame = stack['frames'][debugger.currentFrame];
    Script script = frame['script'];
    return script.load().then((_) {
      var line = script.tokenToLine(frame['tokenPos']);
      // TODO(turnidge): Pass in the column here once the protocol supports it.
      return new Future.value(new SourceLocation.file(script, line, null));
    });
  }

  static Future<SourceLocation> _parseScriptLine(Debugger debugger,
                                                 Match match) {
    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 SourceLocation.error(
          "Line '${lineStr}' must be an integer"));
    }
    if (col == -1) {
      return new Future.value(new SourceLocation.error(
          "Column '${colStr}' must be an integer"));
    }

    if (scriptName != null) {
      // Resolve the script.
      return _lookupScript(debugger.isolate, scriptName).then((scripts) {
        if (scripts.length == 0) {
          return new SourceLocation.error("Script '${scriptName}' not found");
        } else if (scripts.length == 1) {
          return new SourceLocation.file(scripts[0], line, col);
        } else {
          // TODO(turnidge): Allow the user to disambiguate.
          return new SourceLocation.error("Script '${scriptName}' is ambigous");
        }
      });
    } else {
      // No script provided.  Default to top of stack for now.
      ServiceMap stack = debugger.stack;
      if (stack == null || stack['frames'].length == 0) {
        return new Future.value(new SourceLocation.error(
            'A script must be provided when the stack is empty'));
      }
      Script script = stack['frames'][0]['script'];
      return new Future.value(new SourceLocation.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 }) {
    var pending = [];
    for (var lib in isolate.libraries) {
      assert(lib.loaded);
      for (var cls in lib.classes) {
        if (!cls.loaded) {
          pending.add(cls.load());
        }
      }
    }
    return Future.wait(pending).then((_) {
      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) {
    var matches = [];
    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<SourceLocation> _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 SourceLocation.error(
            "Function '${match.group(0)}' not found");
      } else if (functions.length == 1) {
        return new SourceLocation.func(functions[0]);
      } else {
        // TODO(turnidge): Allow the user to disambiguate.
        return new SourceLocation.error(
            "Function '${match.group(0)}' is ambigous");
      }
      return new SourceLocation.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 Future<List<String>> _completeFile(Debugger debugger, Match match) {
    var scriptName = match.group(1);
    var lineStr = match.group(2);
    var colStr = match.group(3);
    if (lineStr != null || colStr != null) {
      // TODO(turnidge): Complete valid line and column numbers.
      return new Future.value([]);
    }
    scriptName = (scriptName == null ? '' : scriptName);

    return _lookupScript(debugger.isolate, scriptName, allowPrefix:true)
      .then((scripts) {
        List completions = [];
        for (var script in scripts) {
          completions.add(script.name + ':');
        }
        completions.sort();
        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);
}
