// Copyright (c) 2014, 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.

library debugger_page_element;

import 'dart:async';
import 'dart:svg';
import 'dart:html';
import 'dart:math';
import 'package:observatory/event.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/app.dart';
import 'package:observatory/cli.dart';
import 'package:observatory/debugger.dart';
import 'package:observatory/src/elements/function_ref.dart';
import 'package:observatory/src/elements/helpers/any_ref.dart';
import 'package:observatory/src/elements/helpers/nav_bar.dart';
import 'package:observatory/src/elements/helpers/nav_menu.dart';
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/src/elements/helpers/uris.dart';
import 'package:observatory/src/elements/instance_ref.dart';
import 'package:observatory/src/elements/nav/isolate_menu.dart';
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/nav/top_menu.dart';
import 'package:observatory/src/elements/nav/vm_menu.dart';
import 'package:observatory/src/elements/source_inset.dart';
import 'package:observatory/src/elements/source_link.dart';
import 'package:observatory/service.dart' as S;
import 'package:logging/logging.dart';

// TODO(turnidge): Move Debugger, DebuggerCommand to debugger library.
abstract class DebuggerCommand extends Command {
  ObservatoryDebugger debugger;

  DebuggerCommand(this.debugger, name, children) : super(name, children);

  String get helpShort;
  String get helpLong;
}

// TODO(turnidge): Rewrite HelpCommand so that it is a general utility
// provided by the cli library.
class HelpCommand extends DebuggerCommand {
  HelpCommand(Debugger debugger)
      : super(debugger, 'help', [
          new HelpHotkeysCommand(debugger),
        ]);

  String _nameAndAlias(Command cmd) {
    if (cmd.alias == null) {
      return cmd.fullName;
    } else {
      return '${cmd.fullName}, ${cmd.alias}';
    }
  }

  Future run(List<String> args) {
    var con = debugger.console;
    if (args.length == 0) {
      // Print list of all top-level commands.
      var commands = debugger.cmd.matchCommand([], false);
      commands.sort((a, b) => a.name.compareTo(b.name));
      con.print('List of commands:\n');
      for (var command in commands) {
        con.print('${_nameAndAlias(command).padRight(12)} '
            '- ${command.helpShort}');
      }
      con.print(
          "\nFor more information on a specific command type 'help <command>'\n"
          "For a list of hotkeys type 'help hotkeys'\n"
          "\n"
          "Command prefixes are accepted (e.g. 'h' for 'help')\n"
          "Hit [TAB] to complete a command (try 'is[TAB][TAB]')\n"
          "Hit [ENTER] to repeat the last command\n"
          "Use up/down arrow for command history\n");
      return new Future.value(null);
    } else {
      // Print any matching commands.
      var commands = debugger.cmd.matchCommand(args, true);
      commands.sort((a, b) => a.name.compareTo(b.name));
      if (commands.isEmpty) {
        var line = args.join(' ');
        con.print("No command matches '${line}'");
        return new Future.value(null);
      }
      con.print('');
      for (var command in commands) {
        con.printBold(_nameAndAlias(command));
        con.print(command.helpLong);

        var newArgs = [];
        newArgs.addAll(args.take(args.length - 1));
        newArgs.add(command.name);
        newArgs.add('');
        var subCommands = debugger.cmd.matchCommand(newArgs, false);
        subCommands.remove(command);
        if (subCommands.isNotEmpty) {
          subCommands.sort((a, b) => a.name.compareTo(b.name));
          con.print('Subcommands:\n');
          for (var subCommand in subCommands) {
            con.print('    ${subCommand.fullName.padRight(16)} '
                '- ${subCommand.helpShort}');
          }
          con.print('');
        }
      }
      return new Future.value(null);
    }
  }

  Future<List<String>> complete(List<String> args) {
    var commands = debugger.cmd.matchCommand(args, false);
    var result = commands.map((command) => '${command.fullName} ');
    return new Future.value(result);
  }

  String helpShort =
      'List commands or provide details about a specific command';

  String helpLong =
      'List commands or provide details about a specific command.\n'
      '\n'
      'Syntax: help            - Show a list of all commands\n'
      '        help <command>  - Help for a specific command\n';
}

class HelpHotkeysCommand extends DebuggerCommand {
  HelpHotkeysCommand(Debugger debugger) : super(debugger, 'hotkeys', []);

  Future run(List<String> args) {
    var con = debugger.console;
    con.print("List of hotkeys:\n"
        "\n"
        "[TAB]        - complete a command\n"
        "[Up Arrow]   - history previous\n"
        "[Down Arrow] - history next\n"
        "\n"
        "[Page Up]    - move up one frame\n"
        "[Page Down]  - move down one frame\n"
        "\n"
        "[F7]         - continue execution of the current isolate\n"
        "[Ctrl ;]     - pause execution of the current isolate\n"
        "\n"
        "[F8]         - toggle breakpoint at current location\n"
        "[F9]         - next\n"
        "[F10]        - step\n"
        "\n");
    return new Future.value(null);
  }

  String helpShort = 'Provide a list of hotkeys';

  String helpLong = 'Provide a list of key hotkeys.\n'
      '\n'
      'Syntax: help hotkeys\n';
}

class PrintCommand extends DebuggerCommand {
  PrintCommand(Debugger debugger) : super(debugger, 'print', []) {
    alias = 'p';
  }

  Future run(List<String> args) async {
    if (args.length < 1) {
      debugger.console.print('print expects arguments');
      return;
    }
    if (debugger.currentFrame == null) {
      debugger.console.print('No stack');
      return;
    }
    var expression = args.join('');
    var response =
        await debugger.isolate.evalFrame(debugger.currentFrame, expression);
    if (response is S.DartError) {
      debugger.console.print(response.message);
    } else {
      debugger.console.print('= ', newline: false);
      debugger.console.printRef(debugger.isolate, response, debugger.instances);
    }
  }

  String helpShort = 'Evaluate and print an expression in the current frame';

  String helpLong = 'Evaluate and print an expression in the current frame.\n'
      '\n'
      'Syntax: print <expression>\n'
      '        p <expression>\n';
}

class DownCommand extends DebuggerCommand {
  DownCommand(Debugger debugger) : super(debugger, 'down', []);

  Future run(List<String> args) {
    int count = 1;
    if (args.length == 1) {
      count = int.parse(args[0]);
    } else if (args.length > 1) {
      debugger.console.print('down expects 0 or 1 argument');
      return new Future.value(null);
    }
    if (debugger.currentFrame == null) {
      debugger.console.print('No stack');
      return new Future.value(null);
    }
    try {
      debugger.downFrame(count);
      debugger.console.print('frame = ${debugger.currentFrame}');
    } catch (e) {
      debugger.console.print('frame must be in range [${e.start},${e.end-1}]');
    }
    return new Future.value(null);
  }

  String helpShort = 'Move down one or more frames (hotkey: [Page Down])';

  String helpLong = 'Move down one or more frames.\n'
      '\n'
      'Hotkey: [Page Down]\n'
      '\n'
      'Syntax: down\n'
      '        down <count>\n';
}

class UpCommand extends DebuggerCommand {
  UpCommand(Debugger debugger) : super(debugger, 'up', []);

  Future run(List<String> args) {
    int count = 1;
    if (args.length == 1) {
      count = int.parse(args[0]);
    } else if (args.length > 1) {
      debugger.console.print('up expects 0 or 1 argument');
      return new Future.value(null);
    }
    if (debugger.currentFrame == null) {
      debugger.console.print('No stack');
      return new Future.value(null);
    }
    try {
      debugger.upFrame(count);
      debugger.console.print('frame = ${debugger.currentFrame}');
    } on RangeError catch (e) {
      debugger.console.print('frame must be in range [${e.start},${e.end-1}]');
    }
    return new Future.value(null);
  }

  String helpShort = 'Move up one or more frames (hotkey: [Page Up])';

  String helpLong = 'Move up one or more frames.\n'
      '\n'
      'Hotkey: [Page Up]\n'
      '\n'
      'Syntax: up\n'
      '        up <count>\n';
}

class FrameCommand extends DebuggerCommand {
  FrameCommand(Debugger debugger) : super(debugger, 'frame', []) {
    alias = 'f';
  }

  Future run(List<String> args) {
    int frame = 1;
    if (args.length == 1) {
      frame = int.parse(args[0]);
    } else {
      debugger.console.print('frame expects 1 argument');
      return new Future.value(null);
    }
    if (debugger.currentFrame == null) {
      debugger.console.print('No stack');
      return new Future.value(null);
    }
    try {
      debugger.currentFrame = frame;
      debugger.console.print('frame = ${debugger.currentFrame}');
    } on RangeError catch (e) {
      debugger.console.print('frame must be in range [${e.start},${e.end-1}]');
    }
    return new Future.value(null);
  }

  String helpShort = 'Set the current frame';

  String helpLong = 'Set the current frame.\n'
      '\n'
      'Syntax: frame <number>\n'
      '        f <count>\n';
}

class PauseCommand extends DebuggerCommand {
  PauseCommand(Debugger debugger) : super(debugger, 'pause', []);

  Future run(List<String> args) {
    return debugger.pause();
  }

  String helpShort = 'Pause the isolate (hotkey: [Ctrl ;])';

  String helpLong = 'Pause the isolate.\n'
      '\n'
      'Hotkey: [Ctrl ;]\n'
      '\n'
      'Syntax: pause\n';
}

class ContinueCommand extends DebuggerCommand {
  ContinueCommand(Debugger debugger) : super(debugger, 'continue', []) {
    alias = 'c';
  }

  Future run(List<String> args) {
    return debugger.resume();
  }

  String helpShort = 'Resume execution of the isolate (hotkey: [F7])';

  String helpLong = 'Continue running the isolate.\n'
      '\n'
      'Hotkey: [F7]\n'
      '\n'
      'Syntax: continue\n'
      '        c\n';
}

class SmartNextCommand extends DebuggerCommand {
  SmartNextCommand(Debugger debugger) : super(debugger, 'next', []) {
    alias = 'n';
  }

  Future run(List<String> args) async {
    return debugger.smartNext();
  }

  String helpShort =
      'Continue running the isolate until it reaches the next source location '
      'in the current function (hotkey: [F9])';

  String helpLong =
      'Continue running the isolate until it reaches the next source location '
      'in the current function.\n'
      '\n'
      'Hotkey: [F9]\n'
      '\n'
      'Syntax: next\n';
}

class SyncNextCommand extends DebuggerCommand {
  SyncNextCommand(Debugger debugger) : super(debugger, 'next-sync', []);

  Future run(List<String> args) {
    return debugger.syncNext();
  }

  String helpShort = 'Run until return/unwind to current activation.';

  String helpLong =
      'Continue running the isolate until control returns to the current '
      'activation or one of its callers.\n'
      '\n'
      'Syntax: next-sync\n';
}

class AsyncNextCommand extends DebuggerCommand {
  AsyncNextCommand(Debugger debugger) : super(debugger, 'next-async', []);

  Future run(List<String> args) {
    return debugger.asyncNext();
  }

  String helpShort = 'Step over await or yield';

  String helpLong =
      'Continue running the isolate until control returns to the current '
      'activation of an async or async* function.\n'
      '\n'
      'Syntax: next-async\n';
}

class StepCommand extends DebuggerCommand {
  StepCommand(Debugger debugger) : super(debugger, 'step', []) {
    alias = 's';
  }

  Future run(List<String> args) {
    return debugger.step();
  }

  String helpShort =
      'Continue running the isolate until it reaches the next source location'
      ' (hotkey: [F10]';

  String helpLong =
      'Continue running the isolate until it reaches the next source '
      'location.\n'
      '\n'
      'Hotkey: [F10]\n'
      '\n'
      'Syntax: step\n';
}

class ClsCommand extends DebuggerCommand {
  ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {}

  Future run(List<String> args) {
    debugger.console.clear();
    debugger.console.newline();
    return new Future.value(null);
  }

  String helpShort = 'Clear the console';

  String helpLong = 'Clear the console.\n'
      '\n'
      'Syntax: cls\n';
}

class LogCommand extends DebuggerCommand {
  LogCommand(Debugger debugger) : super(debugger, 'log', []);

  Future run(List<String> args) async {
    if (args.length == 0) {
      debugger.console.print('Current log level: '
          '${debugger._consolePrinter._minimumLogLevel.name}');
      return new Future.value(null);
    }
    if (args.length > 1) {
      debugger.console.print("log expects zero or one arguments");
      return new Future.value(null);
    }
    var level = _findLevel(args[0]);
    if (level == null) {
      debugger.console.print('No such log level: ${args[0]}');
      return new Future.value(null);
    }
    debugger._consolePrinter._minimumLogLevel = level;
    debugger.console.print('Set log level to: ${level.name}');
    return new Future.value(null);
  }

  Level _findLevel(String levelName) {
    levelName = levelName.toUpperCase();
    for (var level in Level.LEVELS) {
      if (level.name == levelName) {
        return level;
      }
    }
    return null;
  }

  Future<List<String>> complete(List<String> args) {
    if (args.length != 1) {
      return new Future.value([args.join('')]);
    }
    var prefix = args[0].toUpperCase();
    var result = <String>[];
    for (var level in Level.LEVELS) {
      if (level.name.startsWith(prefix)) {
        result.add(level.name);
      }
    }
    return new Future.value(result);
  }

  String helpShort = 'Control which log messages are displayed';

  String helpLong =
      'Get or set the minimum log level that should be displayed.\n'
      '\n'
      'Log levels (in ascending order): ALL, FINEST, FINER, FINE, CONFIG, '
      'INFO, WARNING, SEVERE, SHOUT, OFF\n'
      '\n'
      'Default: OFF\n'
      '\n'
      'Syntax: log          '
      '# Display the current minimum log level.\n'
      '        log <level>  '
      '# Set the minimum log level to <level>.\n'
      '        log OFF      '
      '# Display no log messages.\n'
      '        log ALL      '
      '# Display all log messages.\n';
}

class FinishCommand extends DebuggerCommand {
  FinishCommand(Debugger debugger) : super(debugger, 'finish', []);

  Future run(List<String> args) {
    if (debugger.isolatePaused()) {
      var event = debugger.isolate.pauseEvent;
      if (event is M.PauseStartEvent) {
        debugger.console
            .print("Type 'continue' [F7] or 'step' [F10] to start the isolate");
        return new Future.value(null);
      }
      if (event is M.PauseExitEvent) {
        debugger.console.print("Type 'continue' [F7] to exit the isolate");
        return new Future.value(null);
      }
      return debugger.isolate.stepOut();
    } else {
      debugger.console.print('The program is already running');
      return new Future.value(null);
    }
  }

  String helpShort =
      'Continue running the isolate until the current function exits';

  String helpLong =
      'Continue running the isolate until the current function exits.\n'
      '\n'
      'Syntax: finish\n';
}

class SetCommand extends DebuggerCommand {
  SetCommand(Debugger debugger) : super(debugger, 'set', []);

  static var _boeValues = ['All', 'None', 'Unhandled'];
  static var _boolValues = ['false', 'true'];

  static var _options = {
    'break-on-exception': [
      _boeValues,
      _setBreakOnException,
      (debugger, _) => debugger.breakOnException
    ],
    'up-is-down': [
      _boolValues,
      _setUpIsDown,
      (debugger, _) => debugger.upIsDown
    ],
  };

  static Future _setBreakOnException(debugger, name, value) async {
    var result = await debugger.isolate.setExceptionPauseMode(value);
    if (result.isError) {
      debugger.console.print(result.toString());
    } else {
      // Printing will occur elsewhere.
      debugger.breakOnException = value;
    }
  }

  static Future _setUpIsDown(debugger, name, value) async {
    if (value == 'true') {
      debugger.upIsDown = true;
    } else {
      debugger.upIsDown = false;
    }
    debugger.console.print('${name} = ${value}');
  }

  Future run(List<String> args) async {
    if (args.length == 0) {
      for (var name in _options.keys) {
        var getHandler = _options[name][2];
        var value = await getHandler(debugger, name);
        debugger.console.print("${name} = ${value}");
      }
    } else if (args.length == 1) {
      var name = args[0].trim();
      var optionInfo = _options[name];
      if (optionInfo == null) {
        debugger.console.print("unrecognized option: $name");
        return;
      } else {
        var getHandler = optionInfo[2];
        var value = await getHandler(debugger, name);
        debugger.console.print("${name} = ${value}");
      }
    } else if (args.length == 2) {
      var name = args[0].trim();
      var value = args[1].trim();
      var optionInfo = _options[name];
      if (optionInfo == null) {
        debugger.console.print("unrecognized option: $name");
        return;
      }
      var validValues = optionInfo[0];
      if (!validValues.contains(value)) {
        debugger.console.print("'${value}' is not in ${validValues}");
        return;
      }
      var setHandler = optionInfo[1];
      await setHandler(debugger, name, value);
    } else {
      debugger.console.print("set expects 0, 1, or 2 arguments");
    }
  }

  Future<List<String>> complete(List<String> args) {
    if (args.length < 1 || args.length > 2) {
      return new Future.value([args.join('')]);
    }
    var result = [];
    if (args.length == 1) {
      var prefix = args[0];
      for (var option in _options.keys) {
        if (option.startsWith(prefix)) {
          result.add('${option} ');
        }
      }
    }
    if (args.length == 2) {
      var name = args[0].trim();
      var prefix = args[1];
      var optionInfo = _options[name];
      if (optionInfo != null) {
        var validValues = optionInfo[0];
        for (var value in validValues) {
          if (value.startsWith(prefix)) {
            result.add('${args[0]}${value} ');
          }
        }
      }
    }
    return new Future.value(result);
  }

  String helpShort = 'Set a debugger option';

  String helpLong = 'Set a debugger option.\n'
      '\n'
      'Known options:\n'
      '  break-on-exception    # Should the debugger break on exceptions?\n'
      "                        # ${_boeValues}\n"
      '  up-is-down            # Reverse meaning of up/down commands?\n'
      "                        # ${_boolValues}\n"
      '\n'
      'Syntax: set                    # Display all option settings\n'
      '        set <option>           # Get current value for option\n'
      '        set <option> <value>   # Set value for option';
}

class BreakCommand extends DebuggerCommand {
  BreakCommand(Debugger debugger) : super(debugger, 'break', []);

  Future run(List<String> args) async {
    if (args.length > 1) {
      debugger.console.print('not implemented');
      return;
    }
    var arg = (args.length == 0 ? '' : args[0]);
    var loc = await DebuggerLocation.parse(debugger, arg);
    if (loc.valid) {
      if (loc.function != null) {
        try {
          await debugger.isolate.addBreakpointAtEntry(loc.function);
        } on S.ServerRpcException catch (e) {
          if (e.code == S.ServerRpcException.kCannotAddBreakpoint) {
            debugger.console.print('Unable to set breakpoint at ${loc}');
          } else {
            rethrow;
          }
        }
      } else {
        assert(loc.script != null);
        var script = loc.script;
        await script.load();
        if (loc.line < 1 || loc.line > script.lines.length) {
          debugger.console
              .print('line number must be in range [1,${script.lines.length}]');
          return;
        }
        try {
          await debugger.isolate.addBreakpoint(script, loc.line, loc.col);
        } on S.ServerRpcException catch (e) {
          if (e.code == S.ServerRpcException.kCannotAddBreakpoint) {
            debugger.console.print('Unable to set breakpoint at ${loc}');
          } else {
            rethrow;
          }
        }
      }
    } else {
      debugger.console.print(loc.errorMessage);
    }
  }

  Future<List<String>> complete(List<String> args) {
    if (args.length != 1) {
      return new Future.value([args.join('')]);
    }
    // TODO - fix DebuggerLocation complete
    return new Future.value(DebuggerLocation.complete(debugger, args[0]));
  }

  String helpShort = 'Add a breakpoint by source location or function name'
      ' (hotkey: [F8])';

  String helpLong = 'Add a breakpoint by source location or function name.\n'
      '\n'
      'Hotkey: [F8]\n'
      '\n'
      'Syntax: break                       '
      '# Break at the current position\n'
      '        break <line>                '
      '# Break at a line in the current script\n'
      '                                    '
      '  (e.g \'break 11\')\n'
      '        break <line>:<col>          '
      '# Break at a line:col in the current script\n'
      '                                    '
      '  (e.g \'break 11:8\')\n'
      '        break <script>:<line>       '
      '# Break at a line:col in a specific script\n'
      '                                    '
      '  (e.g \'break test.dart:11\')\n'
      '        break <script>:<line>:<col> '
      '# Break at a line:col in a specific script\n'
      '                                    '
      '  (e.g \'break test.dart:11:8\')\n'
      '        break <function>            '
      '# Break at the named function\n'
      '                                    '
      '  (e.g \'break main\' or \'break Class.someFunction\')\n';
}

class ClearCommand extends DebuggerCommand {
  ClearCommand(Debugger debugger) : super(debugger, 'clear', []);

  Future run(List<String> args) async {
    if (args.length > 1) {
      debugger.console.print('not implemented');
      return;
    }
    var arg = (args.length == 0 ? '' : args[0]);
    var loc = await DebuggerLocation.parse(debugger, arg);
    if (!loc.valid) {
      debugger.console.print(loc.errorMessage);
      return;
    }
    if (loc.function != null) {
      debugger.console.print('Ignoring breakpoint at $loc: '
          'Clearing function breakpoints not yet implemented');
      return;
    }

    var script = loc.script;
    if (loc.line < 1 || loc.line > script.lines.length) {
      debugger.console
          .print('line number must be in range [1,${script.lines.length}]');
      return;
    }
    var lineInfo = script.getLine(loc.line);
    var bpts = lineInfo.breakpoints;
    var foundBreakpoint = false;
    if (bpts != null) {
      var bptList = bpts.toList();
      for (var bpt in bptList) {
        if (loc.col == null ||
            loc.col == script.tokenToCol(bpt.location.tokenPos)) {
          foundBreakpoint = true;
          var result = await debugger.isolate.removeBreakpoint(bpt);
          if (result is S.DartError) {
            debugger.console.print(
                'Error clearing breakpoint ${bpt.number}: ${result.message}');
          }
        }
      }
    }
    if (!foundBreakpoint) {
      debugger.console.print('No breakpoint found at ${loc}');
    }
  }

  Future<List<String>> complete(List<String> args) {
    if (args.length != 1) {
      return new Future.value([args.join('')]);
    }
    return new Future.value(DebuggerLocation.complete(debugger, args[0]));
  }

  String helpShort = 'Remove a breakpoint by source location or function name'
      ' (hotkey: [F8])';

  String helpLong = 'Remove a breakpoint by source location or function name.\n'
      '\n'
      'Hotkey: [F8]\n'
      '\n'
      'Syntax: clear                       '
      '# Clear at the current position\n'
      '        clear <line>                '
      '# Clear at a line in the current script\n'
      '                                    '
      '  (e.g \'clear 11\')\n'
      '        clear <line>:<col>          '
      '# Clear at a line:col in the current script\n'
      '                                    '
      '  (e.g \'clear 11:8\')\n'
      '        clear <script>:<line>       '
      '# Clear at a line:col in a specific script\n'
      '                                    '
      '  (e.g \'clear test.dart:11\')\n'
      '        clear <script>:<line>:<col> '
      '# Clear at a line:col in a specific script\n'
      '                                    '
      '  (e.g \'clear test.dart:11:8\')\n'
      '        clear <function>            '
      '# Clear at the named function\n'
      '                                    '
      '  (e.g \'clear main\' or \'clear Class.someFunction\')\n';
}

// TODO(turnidge): Add argument completion.
class DeleteCommand extends DebuggerCommand {
  DeleteCommand(Debugger debugger) : super(debugger, 'delete', []);

  Future run(List<String> args) {
    if (args.length < 1) {
      debugger.console.print('delete expects one or more arguments');
      return new Future.value(null);
    }
    List toRemove = [];
    for (var arg in args) {
      int id = int.parse(arg);
      var bptToRemove = null;
      for (var bpt in debugger.isolate.breakpoints.values) {
        if (bpt.number == id) {
          bptToRemove = bpt;
          break;
        }
      }
      if (bptToRemove == null) {
        debugger.console.print("Invalid breakpoint id '${id}'");
        return new Future.value(null);
      }
      toRemove.add(bptToRemove);
    }
    List pending = [];
    for (var bpt in toRemove) {
      pending.add(debugger.isolate.removeBreakpoint(bpt));
    }
    return Future.wait(pending);
  }

  String helpShort = 'Remove a breakpoint by breakpoint id';

  String helpLong = 'Remove a breakpoint by breakpoint id.\n'
      '\n'
      'Syntax: delete <bp-id>\n'
      '        delete <bp-id> <bp-id> ...\n';
}

class InfoBreakpointsCommand extends DebuggerCommand {
  InfoBreakpointsCommand(Debugger debugger)
      : super(debugger, 'breakpoints', []);

  Future run(List<String> args) async {
    if (debugger.isolate.breakpoints.isEmpty) {
      debugger.console.print('No breakpoints');
    }
    List bpts = debugger.isolate.breakpoints.values.toList();
    bpts.sort((a, b) => a.number - b.number);
    for (var bpt in bpts) {
      var bpId = bpt.number;
      var locString = await bpt.location.toUserString();
      if (!bpt.resolved) {
        debugger.console.print('Future breakpoint ${bpId} at ${locString}');
      } else {
        debugger.console.print('Breakpoint ${bpId} at ${locString}');
      }
    }
  }

  String helpShort = 'List all breakpoints';

  String helpLong = 'List all breakpoints.\n'
      '\n'
      'Syntax: info breakpoints\n';
}

class InfoFrameCommand extends DebuggerCommand {
  InfoFrameCommand(Debugger debugger) : super(debugger, 'frame', []);

  Future run(List<String> args) {
    if (args.length > 0) {
      debugger.console.print('info frame expects no arguments');
      return new Future.value(null);
    }
    debugger.console.print('frame = ${debugger.currentFrame}');
    return new Future.value(null);
  }

  String helpShort = 'Show current frame';

  String helpLong = 'Show current frame.\n'
      '\n'
      'Syntax: info frame\n';
}

class IsolateCommand extends DebuggerCommand {
  IsolateCommand(Debugger debugger)
      : super(debugger, 'isolate', [
          new IsolateListCommand(debugger),
          new IsolateNameCommand(debugger),
          new IsolateReloadCommand(debugger),
        ]) {
    alias = 'i';
  }

  Future run(List<String> args) {
    if (args.length != 1) {
      debugger.console.print('isolate expects one argument');
      return new Future.value(null);
    }
    var arg = args[0].trim();
    var num = int.parse(arg, onError: (_) => null);

    var candidate;
    for (var isolate in debugger.vm.isolates) {
      if (num != null && num == isolate.number) {
        candidate = isolate;
        break;
      } else if (arg == isolate.name) {
        if (candidate != null) {
          debugger.console.print("Isolate identifier '${arg}' is ambiguous: "
              'use the isolate number instead');
          return new Future.value(null);
        }
        candidate = isolate;
      }
    }
    if (candidate == null) {
      debugger.console.print("Invalid isolate identifier '${arg}'");
    } else {
      if (candidate == debugger.isolate) {
        debugger.console.print(
            "Current isolate is already ${candidate.number} '${candidate.name}'");
      } else {
        new AnchorElement(href: Uris.debugger(candidate)).click();
      }
    }
    return new Future.value(null);
  }

  Future<List<String>> complete(List<String> args) {
    if (args.length != 1) {
      return new Future.value([args.join('')]);
    }
    var result = [];
    for (var isolate in debugger.vm.isolates) {
      var str = isolate.number.toString();
      if (str.startsWith(args[0])) {
        result.add('$str ');
      }
    }
    for (var isolate in debugger.vm.isolates) {
      if (isolate.name.startsWith(args[0])) {
        result.add('${isolate.name} ');
      }
    }
    return new Future.value(result);
  }

  String helpShort = 'Switch, list, rename, or reload isolates';

  String helpLong = 'Switch the current isolate.\n'
      '\n'
      'Syntax: isolate <number>\n'
      '        isolate <name>\n';
}

String _isolateRunState(S.Isolate isolate) {
  if (isolate.paused) {
    return 'paused';
  } else if (isolate.running) {
    return 'running';
  } else if (isolate.idle) {
    return 'idle';
  } else {
    return 'unknown';
  }
}

class IsolateListCommand extends DebuggerCommand {
  IsolateListCommand(Debugger debugger) : super(debugger, 'list', []);

  Future run(List<String> args) async {
    if (debugger.vm == null) {
      debugger.console.print("Internal error: vm has not been set");
      return;
    }

    // Refresh all isolates first.
    var pending = [];
    for (var isolate in debugger.vm.isolates) {
      pending.add(isolate.reload());
    }
    await Future.wait(pending);

    const maxIdLen = 10;
    const maxRunStateLen = 7;
    var maxNameLen = 'NAME'.length;
    for (var isolate in debugger.vm.isolates) {
      maxNameLen = max(maxNameLen, isolate.name.length);
    }
    debugger.console.print("${'ID'.padLeft(maxIdLen, ' ')} "
        "${'ORIGIN'.padLeft(maxIdLen, ' ')} "
        "${'NAME'.padRight(maxNameLen, ' ')} "
        "${'STATE'.padRight(maxRunStateLen, ' ')} "
        "CURRENT");
    for (var isolate in debugger.vm.isolates) {
      String current = (isolate == debugger.isolate ? '*' : '');
      debugger.console
          .print("${isolate.number.toString().padLeft(maxIdLen, ' ')} "
              "${isolate.originNumber.toString().padLeft(maxIdLen, ' ')} "
              "${isolate.name.padRight(maxNameLen, ' ')} "
              "${_isolateRunState(isolate).padRight(maxRunStateLen, ' ')} "
              "${current}");
    }
    debugger.console.newline();
  }

  String helpShort = 'List all isolates';

  String helpLong = 'List all isolates.\n'
      '\n'
      'Syntax: isolate list\n';
}

class IsolateNameCommand extends DebuggerCommand {
  IsolateNameCommand(Debugger debugger) : super(debugger, 'name', []);

  Future run(List<String> args) {
    if (args.length != 1) {
      debugger.console.print('isolate name expects one argument');
      return new Future.value(null);
    }
    return debugger.isolate.setName(args[0]);
  }

  String helpShort = 'Rename the current isolate';

  String helpLong = 'Rename the current isolate.\n'
      '\n'
      'Syntax: isolate name <name>\n';
}

class IsolateReloadCommand extends DebuggerCommand {
  IsolateReloadCommand(Debugger debugger) : super(debugger, 'reload', []);

  Future run(List<String> args) async {
    if (debugger.isolate == null) {
      debugger.console.print('There is no current vm');
      return;
    }

    await debugger.isolate.reloadSources();

    debugger.console.print('Isolate reloading....');
  }

  String helpShort = 'Reload the sources for the current isolate.';

  String helpLong = 'Reload the sources for the current isolate.\n'
      '\n'
      'Syntax: reload\n';
}

class InfoCommand extends DebuggerCommand {
  InfoCommand(Debugger debugger)
      : super(debugger, 'info', [
          new InfoBreakpointsCommand(debugger),
          new InfoFrameCommand(debugger)
        ]);

  Future run(List<String> args) {
    debugger.console.print("'info' expects a subcommand (see 'help info')");
    return new Future.value(null);
  }

  String helpShort = 'Show information on a variety of topics';

  String helpLong = 'Show information on a variety of topics.\n'
      '\n'
      'Syntax: info <subcommand>\n';
}

class RefreshStackCommand extends DebuggerCommand {
  RefreshStackCommand(Debugger debugger) : super(debugger, 'stack', []);

  Future run(List<String> args) {
    return debugger.refreshStack();
  }

  String helpShort = 'Refresh isolate stack';

  String helpLong = 'Refresh isolate stack.\n'
      '\n'
      'Syntax: refresh stack\n';
}

class RefreshCommand extends DebuggerCommand {
  RefreshCommand(Debugger debugger)
      : super(debugger, 'refresh', [
          new RefreshStackCommand(debugger),
        ]);

  Future run(List<String> args) {
    debugger.console
        .print("'refresh' expects a subcommand (see 'help refresh')");
    return new Future.value(null);
  }

  String helpShort = 'Refresh debugging information of various sorts';

  String helpLong = 'Refresh debugging information of various sorts.\n'
      '\n'
      'Syntax: refresh <subcommand>\n';
}

class VmListCommand extends DebuggerCommand {
  VmListCommand(Debugger debugger) : super(debugger, 'list', []);

  Future run(List<String> args) async {
    if (args.length > 0) {
      debugger.console.print('vm list expects no arguments');
      return;
    }
    if (debugger.vm == null) {
      debugger.console.print("No connected VMs");
      return;
    }
    // TODO(turnidge): Right now there is only one vm listed.
    var vmList = [debugger.vm];

    var maxAddrLen = 'ADDRESS'.length;
    var maxNameLen = 'NAME'.length;

    for (var vm in vmList) {
      maxAddrLen = max(maxAddrLen, vm.target.networkAddress.length);
      maxNameLen = max(maxNameLen, vm.name.length);
    }

    debugger.console.print("${'ADDRESS'.padRight(maxAddrLen, ' ')} "
        "${'NAME'.padRight(maxNameLen, ' ')} "
        "CURRENT");
    for (var vm in vmList) {
      String current = (vm == debugger.vm ? '*' : '');
      debugger.console
          .print("${vm.target.networkAddress.padRight(maxAddrLen, ' ')} "
              "${vm.name.padRight(maxNameLen, ' ')} "
              "${current}");
    }
  }

  String helpShort = 'List all connected Dart virtual machines';

  String helpLong = 'List all connected Dart virtual machines..\n'
      '\n'
      'Syntax: vm list\n';
}

class VmNameCommand extends DebuggerCommand {
  VmNameCommand(Debugger debugger) : super(debugger, 'name', []);

  Future run(List<String> args) async {
    if (args.length != 1) {
      debugger.console.print('vm name expects one argument');
      return;
    }
    if (debugger.vm == null) {
      debugger.console.print('There is no current vm');
      return;
    }
    await debugger.vm.setName(args[0]);
  }

  String helpShort = 'Rename the current Dart virtual machine';

  String helpLong = 'Rename the current Dart virtual machine.\n'
      '\n'
      'Syntax: vm name <name>\n';
}

class VmRestartCommand extends DebuggerCommand {
  VmRestartCommand(Debugger debugger) : super(debugger, 'restart', []);

  Future handleModalInput(String line) async {
    if (line == 'yes') {
      debugger.console.printRed('Restarting VM...');
      await debugger.vm.restart();
      debugger.input.exitMode();
    } else if (line == 'no') {
      debugger.console.printRed('VM restart canceled.');
      debugger.input.exitMode();
    } else {
      debugger.console.printRed("Please type 'yes' or 'no'");
    }
  }

  Future run(List<String> args) async {
    debugger.input.enterMode('Restart vm? (yes/no)', handleModalInput);
  }

  String helpShort = 'Restart a Dart virtual machine';

  String helpLong = 'Restart a Dart virtual machine.\n'
      '\n'
      'Syntax: vm restart\n';
}

class VmCommand extends DebuggerCommand {
  VmCommand(Debugger debugger)
      : super(debugger, 'vm', [
          new VmListCommand(debugger),
          new VmNameCommand(debugger),
          new VmRestartCommand(debugger),
        ]);

  Future run(List<String> args) async {
    debugger.console.print("'vm' expects a subcommand (see 'help vm')");
  }

  String helpShort = 'Manage a Dart virtual machine';

  String helpLong = 'Manage a Dart virtual machine.\n'
      '\n'
      'Syntax: vm <subcommand>\n';
}

class _ConsoleStreamPrinter {
  ObservatoryDebugger _debugger;

  _ConsoleStreamPrinter(this._debugger);
  Level _minimumLogLevel = Level.OFF;
  String _savedStream;
  String _savedIsolate;
  String _savedLine;
  List<String> _buffer = [];

  void onEvent(String streamName, S.ServiceEvent event) {
    if (event.kind == S.ServiceEvent.kLogging) {
      // Check if we should print this log message.
      if (event.logRecord['level'].value < _minimumLogLevel.value) {
        return;
      }
    }
    String isolateName = event.isolate.name;
    // If we get a line from a different isolate/stream, flush
    // any pending output, even if it is not newline-terminated.
    if ((_savedIsolate != null && isolateName != _savedIsolate) ||
        (_savedStream != null && streamName != _savedStream)) {
      flush();
    }
    String data;
    bool hasNewline;
    if (event.kind == S.ServiceEvent.kLogging) {
      data = event.logRecord["message"].valueAsString;
      hasNewline = true;
    } else {
      data = event.bytesAsString;
      hasNewline = data.endsWith('\n');
    }
    if (_savedLine != null) {
      data = _savedLine + data;
      _savedIsolate = null;
      _savedStream = null;
      _savedLine = null;
    }
    var lines = data.split('\n').where((line) => line != '').toList();
    if (lines.isEmpty) {
      return;
    }
    int limit = (hasNewline ? lines.length : lines.length - 1);
    for (int i = 0; i < limit; i++) {
      _buffer.add(_format(isolateName, streamName, lines[i]));
    }
    // If there is no newline, we save the last line of output for next time.
    if (!hasNewline) {
      _savedIsolate = isolateName;
      _savedStream = streamName;
      _savedLine = lines[lines.length - 1];
    }
  }

  void flush() {
    // If there is any saved output, flush it now.
    if (_savedLine != null) {
      _buffer.add(_format(_savedIsolate, _savedStream, _savedLine));
      _savedIsolate = null;
      _savedStream = null;
      _savedLine = null;
    }
    if (_buffer.isNotEmpty) {
      _debugger.console.printStdio(_buffer);
      _buffer.clear();
    }
  }

  String _format(String isolateName, String streamName, String line) {
    return '${isolateName}:${streamName}> ${line}';
  }
}

// Tracks the state for an isolate debugging session.
class ObservatoryDebugger extends Debugger {
  final SettingsGroup settings = new SettingsGroup('debugger');
  RootCommand cmd;
  DebuggerPageElement page;
  DebuggerConsoleElement console;
  DebuggerInputElement input;
  DebuggerStackElement stackElement;
  S.ServiceMap stack;
  final S.Isolate isolate;
  String breakOnException = "none"; // Last known setting.

  int get currentFrame => _currentFrame;

  void set currentFrame(int value) {
    if (value != null && (value < 0 || value >= stackDepth)) {
      throw new RangeError.range(value, 0, stackDepth);
    }
    _currentFrame = value;
    if (stackElement != null) {
      stackElement.setCurrentFrame(value);
    }
  }

  int _currentFrame = null;

  bool get upIsDown => _upIsDown;
  void set upIsDown(bool value) {
    settings.set('up-is-down', value);
    _upIsDown = value;
  }

  bool _upIsDown;

  void upFrame(int count) {
    if (_upIsDown) {
      currentFrame += count;
    } else {
      currentFrame -= count;
    }
  }

  void downFrame(int count) {
    if (_upIsDown) {
      currentFrame -= count;
    } else {
      currentFrame += count;
    }
  }

  int get stackDepth => stack['frames'].length;

  static final _history = [''];

  ObservatoryDebugger(this.isolate) {
    _loadSettings();
    cmd = new RootCommand([
      new AsyncNextCommand(this),
      new BreakCommand(this),
      new ClearCommand(this),
      new ClsCommand(this),
      new ContinueCommand(this),
      new DeleteCommand(this),
      new DownCommand(this),
      new FinishCommand(this),
      new FrameCommand(this),
      new HelpCommand(this),
      new InfoCommand(this),
      new IsolateCommand(this),
      new LogCommand(this),
      new PauseCommand(this),
      new PrintCommand(this),
      new RefreshCommand(this),
      new SetCommand(this),
      new SmartNextCommand(this),
      new StepCommand(this),
      new SyncNextCommand(this),
      new UpCommand(this),
      new VmCommand(this),
    ], _history);
    _consolePrinter = new _ConsoleStreamPrinter(this);
  }

  void _loadSettings() {
    _upIsDown = settings.get('up-is-down');
  }

  S.VM get vm => page.app.vm;

  void init() {
    console.printBold('Debugging isolate isolate ${isolate.number} '
        '\'${isolate.name}\' ');
    console.printBold('Type \'h\' for help');
    // Wait a bit and if polymer still hasn't set up the isolate,
    // report this to the user.
    new Timer(const Duration(seconds: 1), () {
      if (isolate == null) {
        reportStatus();
      }
    });

    if ((breakOnException != isolate.exceptionsPauseInfo) &&
        (isolate.exceptionsPauseInfo != null)) {
      breakOnException = isolate.exceptionsPauseInfo;
    }

    isolate.reload().then((response) {
      if (response.isSentinel) {
        // The isolate has gone away.  The IsolateExit event will
        // clear the isolate for the debugger page.
        return;
      }
      // TODO(turnidge): Currently the debugger relies on all libs
      // being loaded.  Fix this.
      var pending = [];
      for (var lib in response.libraries) {
        if (!lib.loaded) {
          pending.add(lib.load());
        }
      }
      Future.wait(pending).then((_) {
        refreshStack();
      }).catchError((e) {
        print("UNEXPECTED ERROR $e");
        reportStatus();
      });
    });
  }

  Future refreshStack() async {
    try {
      if (isolate != null) {
        await _refreshStack(isolate.pauseEvent);
      }
      flushStdio();
      reportStatus();
    } catch (e, st) {
      console.printRed("Unexpected error in refreshStack: $e\n$st");
    }
  }

  bool isolatePaused() {
    // TODO(turnidge): Stop relying on the isolate to track the last
    // pause event.  Since we listen to events directly in the
    // debugger, this could introduce a race.
    return isolate.status == M.IsolateStatus.paused;
  }

  void warnOutOfDate() {
    // Wait a bit, then tell the user that the stack may be out of date.
    new Timer(const Duration(seconds: 2), () {
      if (!isolatePaused()) {
        stackElement.isSampled = true;
      }
    });
  }

  Future<S.ServiceMap> _refreshStack(M.DebugEvent pauseEvent) {
    return isolate.getStack().then((result) {
      if (result.isSentinel) {
        // The isolate has gone away.  The IsolateExit event will
        // clear the isolate for the debugger page.
        return;
      }
      stack = result;
      stackElement.updateStack(stack, pauseEvent);
      if (stack['frames'].length > 0) {
        currentFrame = 0;
      } else {
        currentFrame = null;
      }
      input.focus();
    });
  }

  void reportStatus() {
    flushStdio();
    if (isolate == null) {
      console.print('No current isolate');
    } else if (isolate.idle) {
      console.print('Isolate is idle');
    } else if (isolate.running) {
      console.print("Isolate is running (type 'pause' to interrupt)");
    } else if (isolate.pauseEvent != null) {
      _reportPause(isolate.pauseEvent);
    } else {
      console.print('Isolate is in unknown state');
    }
    warnOutOfDate();
  }

  void _reportIsolateError(S.Isolate isolate, M.DebugEvent event) {
    if (isolate == null) {
      return;
    }
    S.DartError error = isolate.error;
    if (error == null) {
      return;
    }
    console.newline();
    if (event is M.PauseExceptionEvent) {
      console.printBold('Isolate will exit due to an unhandled exception:');
    } else {
      console.printBold('Isolate has exited due to an unhandled exception:');
    }
    console.print(error.message);
    console.newline();
    if (event is M.PauseExceptionEvent &&
        (error.exception.isStackOverflowError ||
            error.exception.isOutOfMemoryError)) {
      console.printBold(
          'When an unhandled stack overflow or OOM exception occurs, the VM '
          'has run out of memory and cannot keep the stack alive while '
          'paused.');
    } else {
      console.printBold("Type 'set break-on-exception Unhandled' to pause the"
          " isolate when an unhandled exception occurs.");
      console.printBold("You can make this the default by running with "
          "--pause-isolates-on-unhandled-exceptions");
    }
  }

  void _reportPause(M.DebugEvent event) {
    if (event is M.NoneEvent) {
      console.print("Paused until embedder makes the isolate runnable.");
    } else if (event is M.PauseStartEvent) {
      console.print("Paused at isolate start "
          "(type 'continue' [F7] or 'step' [F10] to start the isolate')");
    } else if (event is M.PauseExitEvent) {
      console.print("Paused at isolate exit "
          "(type 'continue' or [F7] to exit the isolate')");
      _reportIsolateError(isolate, event);
    } else if (event is M.PauseExceptionEvent) {
      console.print("Paused at an unhandled exception "
          "(type 'continue' or [F7] to exit the isolate')");
      _reportIsolateError(isolate, event);
    } else if (stack['frames'].length > 0) {
      S.Frame frame = stack['frames'][0];
      var script = frame.location.script;
      script.load().then((_) {
        var line = script.tokenToLine(frame.location.tokenPos);
        var col = script.tokenToCol(frame.location.tokenPos);
        if ((event is M.PauseBreakpointEvent) && (event.breakpoint != null)) {
          var bpId = event.breakpoint.number;
          console.print('Paused at breakpoint ${bpId} at '
              '${script.name}:${line}:${col}');
        } else if ((event is M.PauseExceptionEvent) &&
            (event.exception != null)) {
          console.print('Paused due to exception at '
              '${script.name}:${line}:${col}');
          // This seems to be missing if we are paused-at-exception after
          // paused-at-isolate-exit. Maybe we shutdown part of the debugger too
          // soon?
          console.printRef(isolate, event.exception, instances);
        } else {
          console.print('Paused at ${script.name}:${line}:${col}');
        }
      });
    } else {
      console.print("Paused in message loop (type 'continue' or [F7] "
          "to resume processing messages)");
    }
  }

  Future _reportBreakpointEvent(S.ServiceEvent event) async {
    var bpt = event.breakpoint;
    var verb = null;
    switch (event.kind) {
      case S.ServiceEvent.kBreakpointAdded:
        verb = 'added';
        break;
      case S.ServiceEvent.kBreakpointResolved:
        verb = 'resolved';
        break;
      case S.ServiceEvent.kBreakpointRemoved:
        verb = 'removed';
        break;
      default:
        break;
    }
    var script = bpt.location.script;
    await script.load();

    var bpId = bpt.number;
    var locString = await bpt.location.toUserString();
    if (bpt.resolved) {
      console.print('Breakpoint ${bpId} ${verb} at ${locString}');
    } else {
      console.print('Future breakpoint ${bpId} ${verb} at ${locString}');
    }
  }

  void onEvent(S.ServiceEvent event) {
    switch (event.kind) {
      case S.ServiceEvent.kVMUpdate:
        var vm = event.owner;
        console.print("VM ${vm.target.networkAddress} renamed to '${vm.name}'");
        break;

      case S.ServiceEvent.kIsolateStart:
        {
          var iso = event.owner;
          console.print("Isolate ${iso.number} '${iso.name}' has been created");
        }
        break;

      case S.ServiceEvent.kIsolateExit:
        {
          var iso = event.owner;
          if (iso == isolate) {
            console.print("The current isolate ${iso.number} '${iso.name}' "
                "has exited");
            var isolates = vm.isolates;
            if (isolates.length > 0) {
              var newIsolate = isolates.first;
              new AnchorElement(href: Uris.debugger(newIsolate)).click();
            } else {
              new AnchorElement(href: Uris.vm()).click();
            }
          } else {
            console.print("Isolate ${iso.number} '${iso.name}' has exited");
          }
        }
        break;

      case S.ServiceEvent.kDebuggerSettingsUpdate:
        if (breakOnException != event.exceptions) {
          breakOnException = event.exceptions;
          console.print("Now pausing for exceptions: $breakOnException");
        }
        break;

      case S.ServiceEvent.kIsolateUpdate:
        var iso = event.owner;
        console.print("Isolate ${iso.number} renamed to '${iso.name}'");
        break;

      case S.ServiceEvent.kIsolateReload:
        var reloadError = event.reloadError;
        if (reloadError != null) {
          console.print('Isolate reload failed: ${event.reloadError}');
        } else {
          console.print('Isolate reloaded.');
        }
        break;

      case S.ServiceEvent.kPauseStart:
      case S.ServiceEvent.kPauseExit:
      case S.ServiceEvent.kPauseBreakpoint:
      case S.ServiceEvent.kPauseInterrupted:
      case S.ServiceEvent.kPauseException:
        if (event.owner == isolate) {
          var e = createEventFromServiceEvent(event);
          _refreshStack(e).then((_) async {
            flushStdio();
            if (isolate != null) {
              await isolate.reload();
            }
            _reportPause(e);
          });
        }
        break;

      case S.ServiceEvent.kResume:
        if (event.owner == isolate) {
          flushStdio();
          console.print('Continuing...');
        }
        break;

      case S.ServiceEvent.kBreakpointAdded:
      case S.ServiceEvent.kBreakpointResolved:
      case S.ServiceEvent.kBreakpointRemoved:
        if (event.owner == isolate) {
          _reportBreakpointEvent(event);
        }
        break;

      case S.ServiceEvent.kIsolateRunnable:
      case S.ServiceEvent.kGraph:
      case S.ServiceEvent.kGC:
      case S.ServiceEvent.kInspect:
        // Ignore.
        break;

      case S.ServiceEvent.kLogging:
        _consolePrinter.onEvent(event.logRecord['level'].name, event);
        break;

      default:
        console.print('Unrecognized event: $event');
        break;
    }
  }

  _ConsoleStreamPrinter _consolePrinter;

  void flushStdio() {
    _consolePrinter.flush();
  }

  void onStdout(S.ServiceEvent event) {
    _consolePrinter.onEvent('stdout', event);
  }

  void onStderr(S.ServiceEvent event) {
    _consolePrinter.onEvent('stderr', event);
  }

  static String _commonPrefix(String a, String b) {
    int pos = 0;
    while (pos < a.length && pos < b.length) {
      if (a.codeUnitAt(pos) != b.codeUnitAt(pos)) {
        break;
      }
      pos++;
    }
    return a.substring(0, pos);
  }

  static String _foldCompletions(List<String> values) {
    if (values.length == 0) {
      return '';
    }
    var prefix = values[0];
    for (int i = 1; i < values.length; i++) {
      prefix = _commonPrefix(prefix, values[i]);
    }
    return prefix;
  }

  Future<String> complete(String line) {
    return cmd.completeCommand(line).then((completions) {
      if (completions.length == 0) {
        // No completions.  Leave the line alone.
        return line;
      } else if (completions.length == 1) {
        // Unambiguous completion.
        return completions[0];
      } else {
        // Ambiguous completion.
        completions = completions.map((s) => s.trimRight()).toList();
        console.printBold(completions.toString());
        return _foldCompletions(completions);
      }
    });
  }

  // TODO(turnidge): Implement real command line history.
  String lastCommand;

  Future run(String command) {
    if (command == '' && lastCommand != null) {
      command = lastCommand;
    }
    console.printBold('\$ $command');
    return cmd.runCommand(command).then((_) {
      lastCommand = command;
    }).catchError((e, s) {
      if (e is S.NetworkRpcException) {
        console.printRed('Unable to execute command because the connection '
            'to the VM has been closed');
      } else {
        if (s != null) {
          console.printRed('Internal error: $e\n$s');
        } else {
          console.printRed('Internal error: $e\n');
        }
      }
    });
  }

  String historyPrev(String command) {
    return cmd.historyPrev(command);
  }

  String historyNext(String command) {
    return cmd.historyNext(command);
  }

  Future pause() {
    if (!isolatePaused()) {
      return isolate.pause();
    } else {
      console.print('The program is already paused');
      return new Future.value(null);
    }
  }

  Future resume() {
    if (isolatePaused()) {
      return isolate.resume().then((_) {
        warnOutOfDate();
      });
    } else {
      console.print('The program must be paused');
      return new Future.value(null);
    }
  }

  Future toggleBreakpoint() async {
    var loc = await DebuggerLocation.parse(this, '');
    var script = loc.script;
    var line = loc.line;
    if (script != null && line != null) {
      var bpts = script.getLine(line).breakpoints;
      if (bpts == null || bpts.isEmpty) {
        // Set a new breakpoint.
        // TODO(turnidge): Set this breakpoint at current column.
        await isolate.addBreakpoint(script, line);
      } else {
        // TODO(turnidge): Clear this breakpoint at current column.
        var pending = [];
        for (var bpt in bpts) {
          pending.add(isolate.removeBreakpoint(bpt));
        }
        await Future.wait(pending);
      }
    }
    return new Future.value(null);
  }

  Future smartNext() async {
    if (isolatePaused()) {
      var event = isolate.pauseEvent;
      if (event.atAsyncSuspension) {
        return asyncNext();
      } else {
        return syncNext();
      }
    } else {
      console.print('The program is already running');
    }
  }

  Future asyncNext() async {
    if (isolatePaused()) {
      var event = isolate.pauseEvent;
      if (!event.atAsyncSuspension) {
        console.print("No async continuation at this location");
      } else {
        return isolate.stepOverAsyncSuspension();
      }
    } else {
      console.print('The program is already running');
    }
  }

  Future syncNext() async {
    if (isolatePaused()) {
      var event = isolate.pauseEvent;
      if (event is M.PauseStartEvent) {
        console
            .print("Type 'continue' [F7] or 'step' [F10] to start the isolate");
        return null;
      }
      if (event is M.PauseExitEvent) {
        console.print("Type 'continue' [F7] to exit the isolate");
        return null;
      }
      return isolate.stepOver();
    } else {
      console.print('The program is already running');
      return null;
    }
  }

  Future step() {
    if (isolatePaused()) {
      var event = isolate.pauseEvent;
      if (event is M.PauseExitEvent) {
        console.print("Type 'continue' [F7] to exit the isolate");
        return new Future.value(null);
      }
      return isolate.stepInto();
    } else {
      console.print('The program is already running');
      return new Future.value(null);
    }
  }
}

class DebuggerPageElement extends HtmlElement implements Renderable {
  static const tag =
      const Tag<DebuggerPageElement>('debugger-page', dependencies: const [
    NavTopMenuElement.tag,
    NavVMMenuElement.tag,
    NavIsolateMenuElement.tag,
    NavNotifyElement.tag,
  ]);

  S.Isolate _isolate;
  ObservatoryDebugger _debugger;
  M.InstanceRepository _instances;
  M.ScriptRepository _scripts;
  M.EventRepository _events;

  factory DebuggerPageElement(S.Isolate isolate, M.InstanceRepository instances,
      M.ScriptRepository scripts, M.EventRepository events) {
    assert(isolate != null);
    assert(instances != null);
    assert(scripts != null);
    assert(events != null);
    final e = document.createElement(tag.name);
    final debugger = new ObservatoryDebugger(isolate);
    debugger.page = e;
    e._isolate = isolate;
    e._debugger = debugger;
    e._instances = instances;
    e._scripts = scripts;
    e._events = events;
    return e;
  }

  DebuggerPageElement.created() : super.created();

  Future<StreamSubscription> _vmSubscriptionFuture;
  Future<StreamSubscription> _isolateSubscriptionFuture;
  Future<StreamSubscription> _debugSubscriptionFuture;
  Future<StreamSubscription> _stdoutSubscriptionFuture;
  Future<StreamSubscription> _stderrSubscriptionFuture;
  Future<StreamSubscription> _logSubscriptionFuture;

  ObservatoryApplication get app => ObservatoryApplication.app;

  Timer _timer;

  static final consoleElement = new DebuggerConsoleElement();

  @override
  void attached() {
    super.attached();

    final stackDiv = new DivElement()..classes = ['stack'];
    final stackElement = new DebuggerStackElement(
        _isolate, _debugger, stackDiv, _instances, _scripts, _events);
    stackDiv.children = [stackElement];
    final consoleDiv = new DivElement()
      ..classes = ['console']
      ..children = [consoleElement];
    final commandElement = new DebuggerInputElement(_isolate, _debugger);
    final commandDiv = new DivElement()
      ..classes = ['commandline']
      ..children = [commandElement];

    children = [
      navBar([
        new NavTopMenuElement(queue: app.queue),
        new NavVMMenuElement(app.vm, app.events, queue: app.queue),
        new NavIsolateMenuElement(_isolate, app.events, queue: app.queue),
        navMenu('debugger'),
        new NavNotifyElement(app.notifications,
            notifyOnPause: false, queue: app.queue)
      ]),
      new DivElement()
        ..classes = ['variable']
        ..children = [
          stackDiv,
          new DivElement()
            ..children = [
              new HRElement()..classes = ['splitter']
            ],
          consoleDiv,
        ],
      commandDiv
    ];

    DebuggerConsoleElement._scrollToBottom(consoleDiv);

    // Wire the debugger object to the stack, console, and command line.
    _debugger.stackElement = stackElement;
    _debugger.console = consoleElement;
    _debugger.input = commandElement;
    _debugger.input._debugger = _debugger;
    _debugger.init();

    _vmSubscriptionFuture =
        app.vm.listenEventStream(S.VM.kVMStream, _debugger.onEvent);
    _isolateSubscriptionFuture =
        app.vm.listenEventStream(S.VM.kIsolateStream, _debugger.onEvent);
    _debugSubscriptionFuture =
        app.vm.listenEventStream(S.VM.kDebugStream, _debugger.onEvent);
    _stdoutSubscriptionFuture =
        app.vm.listenEventStream(S.VM.kStdoutStream, _debugger.onStdout);
    if (_stdoutSubscriptionFuture != null) {
      // TODO(turnidge): How do we want to handle this in general?
      _stdoutSubscriptionFuture.catchError((e, st) {
        Logger.root.info('Failed to subscribe to stdout: $e\n$st\n');
        _stdoutSubscriptionFuture = null;
      });
    }
    _stderrSubscriptionFuture =
        app.vm.listenEventStream(S.VM.kStderrStream, _debugger.onStderr);
    if (_stderrSubscriptionFuture != null) {
      // TODO(turnidge): How do we want to handle this in general?
      _stderrSubscriptionFuture.catchError((e, st) {
        Logger.root.info('Failed to subscribe to stderr: $e\n$st\n');
        _stderrSubscriptionFuture = null;
      });
    }
    _logSubscriptionFuture =
        app.vm.listenEventStream(S.Isolate.kLoggingStream, _debugger.onEvent);
    // Turn on the periodic poll timer for this page.
    _timer = new Timer.periodic(const Duration(milliseconds: 100), (_) {
      _debugger.flushStdio();
    });

    onClick.listen((event) {
      // Random clicks should focus on the text box.  If the user selects
      // a range, don't interfere.
      var selection = window.getSelection();
      if (selection == null ||
          (selection.type != 'Range' && selection.type != 'text')) {
        _debugger.input.focus();
      }
    });
  }

  @override
  void render() {
    /* nothing to do */
  }

  @override
  void detached() {
    _timer.cancel();
    children = const [];
    S.cancelFutureSubscription(_vmSubscriptionFuture);
    _vmSubscriptionFuture = null;
    S.cancelFutureSubscription(_isolateSubscriptionFuture);
    _isolateSubscriptionFuture = null;
    S.cancelFutureSubscription(_debugSubscriptionFuture);
    _debugSubscriptionFuture = null;
    S.cancelFutureSubscription(_stdoutSubscriptionFuture);
    _stdoutSubscriptionFuture = null;
    S.cancelFutureSubscription(_stderrSubscriptionFuture);
    _stderrSubscriptionFuture = null;
    S.cancelFutureSubscription(_logSubscriptionFuture);
    _logSubscriptionFuture = null;
    super.detached();
  }
}

class DebuggerStackElement extends HtmlElement implements Renderable {
  static const tag = const Tag<DebuggerStackElement>('debugger-stack');

  S.Isolate _isolate;
  M.InstanceRepository _instances;
  M.ScriptRepository _scripts;
  M.EventRepository _events;
  Element _scroller;
  DivElement _isSampled;
  bool get isSampled => !_isSampled.classes.contains('hidden');
  set isSampled(bool value) {
    if (value != isSampled) {
      _isSampled.classes.toggle('hidden');
    }
  }

  DivElement _hasStack;
  bool get hasStack => _hasStack.classes.contains('hidden');
  set hasStack(bool value) {
    if (value != hasStack) {
      _hasStack.classes.toggle('hidden');
    }
  }

  DivElement _hasMessages;
  bool get hasMessages => _hasMessages.classes.contains('hidden');
  set hasMessages(bool value) {
    if (value != hasMessages) {
      _hasMessages.classes.toggle('hidden');
    }
  }

  UListElement _frameList;
  UListElement _messageList;
  int currentFrame;
  ObservatoryDebugger _debugger;

  factory DebuggerStackElement(
      S.Isolate isolate,
      ObservatoryDebugger debugger,
      Element scroller,
      M.InstanceRepository instances,
      M.ScriptRepository scripts,
      M.EventRepository events) {
    assert(isolate != null);
    assert(debugger != null);
    assert(scroller != null);
    assert(instances != null);
    assert(scripts != null);
    assert(events != null);
    final e = document.createElement(tag.name);
    e._isolate = isolate;
    e._debugger = debugger;
    e._scroller = scroller;
    e._instances = instances;
    e._scripts = scripts;
    e._events = events;

    var btnPause;
    var btnRefresh;
    e.children = [
      e._isSampled = new DivElement()
        ..classes = ['sampledMessage', 'hidden']
        ..children = [
          new SpanElement()
            ..text = 'The program is not paused. '
                'The stack trace below may be out of date.',
          new BRElement(),
          new BRElement(),
          btnPause = new ButtonElement()
            ..text = '[Pause Isolate]'
            ..onClick.listen((_) async {
              btnPause.disabled = true;
              try {
                await debugger.isolate.pause();
              } finally {
                btnPause.disabled = false;
              }
            }),
          btnRefresh = new ButtonElement()
            ..text = '[Refresh Stack]'
            ..onClick.listen((_) async {
              btnRefresh.disabled = true;
              try {
                await debugger.refreshStack();
              } finally {
                btnRefresh.disabled = false;
              }
            }),
          new BRElement(),
          new BRElement(),
          new HRElement()..classes = ['splitter']
        ],
      e._hasStack = new DivElement()
        ..classes = ['noStack', 'hidden']
        ..text = 'No stack',
      e._frameList = new UListElement()..classes = ['list-group'],
      new HRElement(),
      e._hasMessages = new DivElement()
        ..classes = ['noMessages', 'hidden']
        ..text = 'No pending messages',
      e._messageList = new UListElement()..classes = ['messageList']
    ];
    return e;
  }

  void render() {
    /* nothing to do */
  }

  _addFrame(List frameList, S.Frame frameInfo) {
    final frameElement = new DebuggerFrameElement(
        _isolate, frameInfo, _scroller, _instances, _scripts, _events,
        queue: app.queue);

    if (frameInfo.index == currentFrame) {
      frameElement.setCurrent(true);
    } else {
      frameElement.setCurrent(false);
    }

    var li = new LIElement();
    li.classes.add('list-group-item');
    li.children.insert(0, frameElement);

    frameList.insert(0, li);
  }

  _addMessage(List messageList, S.ServiceMessage messageInfo) {
    final messageElement = new DebuggerMessageElement(
        _isolate, messageInfo, _instances, _scripts, _events,
        queue: app.queue);

    var li = new LIElement();
    li.classes.add('list-group-item');
    li.children.insert(0, messageElement);

    messageList.add(li);
  }

  ObservatoryApplication get app => ObservatoryApplication.app;

  void updateStackFrames(S.ServiceMap newStack) {
    List frameElements = _frameList.children;
    List newFrames = newStack['frames'];

    // Remove any frames whose functions don't match, starting from
    // bottom of stack.
    int oldPos = frameElements.length - 1;
    int newPos = newFrames.length - 1;
    while (oldPos >= 0 && newPos >= 0) {
      if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) {
        // The rest of the frame elements no longer match.  Remove them.
        for (int i = 0; i <= oldPos; i++) {
          // NOTE(turnidge): removeRange is missing, sadly.
          frameElements.removeAt(0);
        }
        break;
      }
      oldPos--;
      newPos--;
    }

    // Remove any extra frames.
    if (frameElements.length > newFrames.length) {
      // Remove old frames from the top of stack.
      int removeCount = frameElements.length - newFrames.length;
      for (int i = 0; i < removeCount; i++) {
        frameElements.removeAt(0);
      }
    }

    // Add any new frames.
    int newCount = 0;
    if (frameElements.length < newFrames.length) {
      // Add new frames to the top of stack.
      newCount = newFrames.length - frameElements.length;
      for (int i = newCount - 1; i >= 0; i--) {
        _addFrame(frameElements, newFrames[i]);
      }
    }
    assert(frameElements.length == newFrames.length);

    if (frameElements.isNotEmpty) {
      for (int i = newCount; i < frameElements.length; i++) {
        frameElements[i].children[0].updateFrame(newFrames[i]);
      }
    }

    hasStack = frameElements.isNotEmpty;
  }

  void updateStackMessages(S.ServiceMap newStack) {
    List messageElements = _messageList.children;
    List newMessages = newStack['messages'];

    // Remove any extra message elements.
    if (messageElements.length > newMessages.length) {
      // Remove old messages from the front of the queue.
      int removeCount = messageElements.length - newMessages.length;
      for (int i = 0; i < removeCount; i++) {
        messageElements.removeAt(0);
      }
    }

    // Add any new messages to the tail of the queue.
    int newStartingIndex = messageElements.length;
    if (messageElements.length < newMessages.length) {
      for (int i = newStartingIndex; i < newMessages.length; i++) {
        _addMessage(messageElements, newMessages[i]);
      }
    }
    assert(messageElements.length == newMessages.length);

    if (messageElements.isNotEmpty) {
      // Update old messages.
      for (int i = 0; i < newStartingIndex; i++) {
        DebuggerMessageElement e = messageElements[i].children[0];
        e.updateMessage(newMessages[i]);
      }
    }

    hasMessages = messageElements.isNotEmpty;
  }

  void updateStack(S.ServiceMap newStack, M.DebugEvent pauseEvent) {
    updateStackFrames(newStack);
    updateStackMessages(newStack);
    isSampled = pauseEvent == null;
  }

  void setCurrentFrame(int value) {
    currentFrame = value;
    List frameElements = _frameList.children;
    for (var frameElement in frameElements) {
      DebuggerFrameElement dbgFrameElement = frameElement.children[0];
      if (dbgFrameElement.frame.index == currentFrame) {
        dbgFrameElement.setCurrent(true);
      } else {
        dbgFrameElement.setCurrent(false);
      }
    }
  }

  DebuggerStackElement.created() : super.created();
}

class DebuggerFrameElement extends HtmlElement implements Renderable {
  static const tag = const Tag<DebuggerFrameElement>('debugger-frame');

  RenderingScheduler<DebuggerMessageElement> _r;

  Stream<RenderedEvent<DebuggerMessageElement>> get onRendered => _r.onRendered;

  Element _scroller;
  DivElement _varsDiv;
  M.Isolate _isolate;
  S.Frame _frame;
  S.Frame get frame => _frame;
  M.InstanceRepository _instances;
  M.ScriptRepository _scripts;
  M.EventRepository _events;

  // Is this the current frame?
  bool _current = false;

  // Has this frame been pinned open?
  bool _pinned = false;

  bool _expanded = false;

  void setCurrent(bool value) {
    _frame.function.load().then((func) {
      _current = value;
      if (_current) {
        _expand();
        scrollIntoView();
      } else {
        if (_pinned) {
          _expand();
        } else {
          _unexpand();
        }
      }
    });
  }

  factory DebuggerFrameElement(
      M.Isolate isolate,
      S.Frame frame,
      Element scroller,
      M.InstanceRepository instances,
      M.ScriptRepository scripts,
      M.EventRepository events,
      {RenderingQueue queue}) {
    assert(isolate != null);
    assert(frame != null);
    assert(scroller != null);
    assert(instances != null);
    assert(scripts != null);
    assert(events != null);
    final DebuggerFrameElement e = document.createElement(tag.name);
    e._r = new RenderingScheduler(e, queue: queue);
    e._isolate = isolate;
    e._frame = frame;
    e._scroller = scroller;
    e._instances = instances;
    e._scripts = scripts;
    e._events = events;
    return e;
  }

  DebuggerFrameElement.created() : super.created();

  void render() {
    if (_pinned) {
      classes.add('shadow');
    } else {
      classes.remove('shadow');
    }
    if (_current) {
      classes.add('current');
    } else {
      classes.remove('current');
    }
    ButtonElement expandButton;
    final content = <Element>[
      expandButton = new ButtonElement()
        ..children = _createHeader()
        ..onClick.listen((e) async {
          if (e.target is AnchorElement) {
            return;
          }
          expandButton.disabled = true;
          await _toggleExpand();
          expandButton.disabled = false;
        })
    ];
    if (_expanded) {
      final homeMethod = _frame.function.homeMethod;
      String homeMethodName;
      if ((homeMethod.dartOwner is S.Class) && homeMethod.isStatic) {
        homeMethodName = '<class>';
      } else if (homeMethod.dartOwner is S.Library) {
        homeMethodName = '<library>';
      }
      ButtonElement collapseButton;
      content.addAll([
        new DivElement()
          ..classes = ['frameDetails']
          ..children = [
            new DivElement()
              ..classes = ['flex-row-wrap']
              ..children = [
                new DivElement()
                  ..classes = ['flex-item-script']
                  ..children = _frame.function?.location == null
                      ? const []
                      : [
                          new SourceInsetElement(
                              _isolate,
                              _frame.function.location,
                              _scripts,
                              _instances,
                              _events,
                              currentPos: _frame.location.tokenPos,
                              variables: _frame.variables,
                              inDebuggerContext: true,
                              queue: _r.queue)
                        ],
                new DivElement()
                  ..classes = ['flex-item-vars']
                  ..children = [
                    _varsDiv = new DivElement()
                      ..classes = ['memberList', 'frameVars']
                      ..children = ([
                        new DivElement()
                          ..classes = ['memberItem']
                          ..children = homeMethodName == null
                              ? const []
                              : [
                                  new DivElement()
                                    ..classes = ['memberName']
                                    ..text = homeMethodName,
                                  new DivElement()
                                    ..classes = ['memberName']
                                    ..children = [
                                      anyRef(_isolate, homeMethod.dartOwner,
                                          _instances,
                                          queue: _r.queue)
                                    ]
                                ]
                      ]
                        ..addAll(_frame.variables
                            .map((v) => new DivElement()
                              ..classes = ['memberItem']
                              ..children = [
                                new DivElement()
                                  ..classes = ['memberName']
                                  ..text = v.name,
                                new DivElement()
                                  ..classes = ['memberName']
                                  ..children = [
                                    anyRef(_isolate, v['value'], _instances,
                                        queue: _r.queue)
                                  ]
                              ])
                            .toList()))
                  ]
              ],
            new DivElement()
              ..classes = ['frameContractor']
              ..children = [
                collapseButton = new ButtonElement()
                  ..onClick.listen((e) async {
                    collapseButton.disabled = true;
                    await _toggleExpand();
                    collapseButton.disabled = false;
                  })
                  ..children = [iconExpandLess.clone(true)]
              ]
          ]
      ]);
    }
    children = content;
  }

  List<Element> _createHeader() {
    final content = [
      new DivElement()
        ..classes = ['frameSummaryText']
        ..children = [
          new DivElement()
            ..classes = ['frameId']
            ..text = 'Frame ${_frame.index}',
          new SpanElement()
            ..children = _frame.function == null
                ? const []
                : [
                    new FunctionRefElement(_isolate, _frame.function,
                        queue: _r.queue)
                  ],
          new SpanElement()..text = ' ( ',
          new SpanElement()
            ..children = _frame.function?.location == null
                ? const []
                : [
                    new SourceLinkElement(
                        _isolate, _frame.function.location, _scripts,
                        queue: _r.queue)
                  ],
          new SpanElement()..text = ' )'
        ]
    ];
    if (!_expanded) {
      content.add(new DivElement()
        ..classes = ['frameExpander']
        ..children = [iconExpandMore.clone(true)]);
    }
    return [
      new DivElement()
        ..classes = ['frameSummary']
        ..children = content
    ];
  }

  String makeExpandKey(String key) {
    return '${_frame.function.qualifiedName}/${key}';
  }

  bool matchFrame(S.Frame newFrame) {
    return newFrame.function.id == _frame.function.id;
  }

  void updateFrame(S.Frame newFrame) {
    assert(matchFrame(newFrame));
    _frame = newFrame;
  }

  S.Script get script => _frame.location.script;

  int _varsTop(varsDiv) {
    const minTop = 0;
    if (varsDiv == null) {
      return minTop;
    }
    final paddingTop = document.body.contentEdge.top;
    final parent = varsDiv.parent.getBoundingClientRect();
    final varsHeight = varsDiv.clientHeight;
    final maxTop = parent.height - varsHeight;
    final adjustedTop = paddingTop - parent.top;
    return (max(minTop, min(maxTop, adjustedTop)));
  }

  void _onScroll(event) {
    if (!_expanded || _varsDiv == null) {
      return;
    }
    var currentTop = _varsDiv.style.top;
    var newTop = _varsTop(_varsDiv);
    if (currentTop != newTop) {
      _varsDiv.style.top = '${newTop}px';
    }
  }

  void _expand() {
    _expanded = true;
    _subscribeToScroll();
    _r.dirty();
  }

  void _unexpand() {
    _expanded = false;
    _unsubscribeToScroll();
    _r.dirty();
  }

  StreamSubscription _scrollSubscription;
  StreamSubscription _resizeSubscription;

  void _subscribeToScroll() {
    if (_scroller != null) {
      if (_scrollSubscription == null) {
        _scrollSubscription = _scroller.onScroll.listen(_onScroll);
      }
      if (_resizeSubscription == null) {
        _resizeSubscription = window.onResize.listen(_onScroll);
      }
    }
  }

  void _unsubscribeToScroll() {
    if (_scrollSubscription != null) {
      _scrollSubscription.cancel();
      _scrollSubscription = null;
    }
    if (_resizeSubscription != null) {
      _resizeSubscription.cancel();
      _resizeSubscription = null;
    }
  }

  @override
  void attached() {
    super.attached();
    _r.enable();
    if (_expanded) {
      _subscribeToScroll();
    }
  }

  void detached() {
    _r.disable(notify: true);
    super.detached();
    _unsubscribeToScroll();
  }

  Future _toggleExpand() async {
    await _frame.function.load();
    _pinned = !_pinned;
    if (_pinned) {
      _expand();
    } else {
      _unexpand();
    }
  }
}

class DebuggerMessageElement extends HtmlElement implements Renderable {
  static const tag = const Tag<DebuggerMessageElement>('debugger-message');

  RenderingScheduler<DebuggerMessageElement> _r;

  Stream<RenderedEvent<DebuggerMessageElement>> get onRendered => _r.onRendered;

  S.Isolate _isolate;
  S.ServiceMessage _message;
  S.ServiceObject _preview;
  M.InstanceRepository _instances;
  M.ScriptRepository _scripts;
  M.EventRepository _events;

  // Is this the current message?
  bool _current = false;

  // Has this message been pinned open?
  bool _pinned = false;

  bool _expanded = false;

  factory DebuggerMessageElement(
      S.Isolate isolate,
      S.ServiceMessage message,
      M.InstanceRepository instances,
      M.ScriptRepository scripts,
      M.EventRepository events,
      {RenderingQueue queue}) {
    assert(isolate != null);
    assert(message != null);
    assert(instances != null);
    assert(instances != null);
    assert(events != null);
    final DebuggerMessageElement e = document.createElement(tag.name);
    e._r = new RenderingScheduler(e, queue: queue);
    e._isolate = isolate;
    e._message = message;
    e._instances = instances;
    e._scripts = scripts;
    e._events = events;
    return e;
  }

  DebuggerMessageElement.created() : super.created();

  void render() {
    if (_pinned) {
      classes.add('shadow');
    } else {
      classes.remove('shadow');
    }
    if (_current) {
      classes.add('current');
    } else {
      classes.remove('current');
    }
    ButtonElement expandButton;
    final content = <Element>[
      expandButton = new ButtonElement()
        ..children = _createHeader()
        ..onClick.listen((e) async {
          if (e.target is AnchorElement) {
            return;
          }
          expandButton.disabled = true;
          await _toggleExpand();
          expandButton.disabled = false;
        })
    ];
    if (_expanded) {
      ButtonElement collapseButton;
      ButtonElement previewButton;
      content.addAll([
        new DivElement()
          ..classes = ['messageDetails']
          ..children = [
            new DivElement()
              ..classes = ['flex-row-wrap']
              ..children = [
                new DivElement()
                  ..classes = ['flex-item-script']
                  ..children = _message.handler == null
                      ? const []
                      : [
                          new SourceInsetElement(
                              _isolate,
                              _message.handler.location,
                              _scripts,
                              _instances,
                              _events,
                              inDebuggerContext: true,
                              queue: _r.queue)
                        ],
                new DivElement()
                  ..classes = ['flex-item-vars']
                  ..children = [
                    new DivElement()
                      ..classes = ['memberItem']
                      ..children = [
                        new DivElement()..classes = ['memberName'],
                        new DivElement()
                          ..classes = ['memberValue']
                          ..children = ([
                            previewButton = new ButtonElement()
                              ..text = 'preview'
                              ..onClick.listen((_) {
                                previewButton.disabled = true;
                              })
                          ]
                            ..addAll(_preview == null
                                ? const []
                                : [
                                    anyRef(_isolate, _preview, _instances,
                                        queue: _r.queue)
                                  ]))
                      ]
                  ]
              ],
            new DivElement()
              ..classes = ['messageContractor']
              ..children = [
                collapseButton = new ButtonElement()
                  ..onClick.listen((e) async {
                    collapseButton.disabled = true;
                    await _toggleExpand();
                    collapseButton.disabled = false;
                  })
                  ..children = [iconExpandLess.clone(true)]
              ]
          ]
      ]);
    }
    children = content;
  }

  void updateMessage(S.ServiceMessage message) {
    assert(_message != null);
    _message = message;
    _r.dirty();
  }

  List<Element> _createHeader() {
    final content = [
      new DivElement()
        ..classes = ['messageSummaryText']
        ..children = [
          new DivElement()
            ..classes = ['messageId']
            ..text = 'message ${_message.index}',
          new SpanElement()
            ..children = _message.handler == null
                ? const []
                : [
                    new FunctionRefElement(_isolate, _message.handler,
                        queue: _r.queue)
                  ],
          new SpanElement()..text = ' ( ',
          new SpanElement()
            ..children = _message.location == null
                ? const []
                : [
                    new SourceLinkElement(_isolate, _message.location, _scripts,
                        queue: _r.queue)
                  ],
          new SpanElement()..text = ' )'
        ]
    ];
    if (!_expanded) {
      content.add(new DivElement()
        ..classes = ['messageExpander']
        ..children = [iconExpandMore.clone(true)]);
    }
    return [
      new DivElement()
        ..classes = ['messageSummary']
        ..children = content
    ];
  }

  void setCurrent(bool value) {
    _current = value;
    if (_current) {
      _expanded = true;
      scrollIntoView();
      _r.dirty();
    } else {
      _expanded = _pinned;
    }
  }

  @override
  void attached() {
    super.attached();
    _r.enable();
  }

  @override
  void detached() {
    super.detached();
    _r.disable(notify: true);
    children = [];
  }

  Future _toggleExpand() async {
    var function = _message.handler;
    if (function != null) {
      await function.load();
    }
    _pinned = _pinned;
    _expanded = true;
    _r.dirty();
  }

  Future<S.ServiceObject> previewMessage(_) {
    return _message.isolate.getObject(_message.messageObjectId).then((result) {
      _preview = result;
      return result;
    });
  }
}

class DebuggerConsoleElement extends HtmlElement implements Renderable {
  static const tag = const Tag<DebuggerConsoleElement>('debugger-console');

  factory DebuggerConsoleElement() {
    final DebuggerConsoleElement e = document.createElement(tag.name);
    e.children = [new BRElement()];
    return e;
  }

  DebuggerConsoleElement.created() : super.created();

  /// Is [container] scrolled to the within [threshold] pixels of the bottom?
  static bool _isScrolledToBottom(DivElement container, [int threshold = 2]) {
    if (container == null) {
      return false;
    }
    // scrollHeight -> complete height of element including scrollable area.
    // clientHeight -> height of element on page.
    // scrollTop -> how far is an element scrolled (from 0 to scrollHeight).
    final distanceFromBottom =
        container.scrollHeight - container.clientHeight - container.scrollTop;
    const threshold = 2; // 2 pixel slop.
    return distanceFromBottom <= threshold;
  }

  /// Scroll [container] so the bottom content is visible.
  static _scrollToBottom(DivElement container) {
    if (container == null) {
      return;
    }
    // Adjust scroll so that the bottom of the content is visible.
    container.scrollTop = container.scrollHeight - container.clientHeight;
  }

  void _append(HtmlElement span) {
    bool autoScroll = _isScrolledToBottom(parent);
    children.add(span);
    if (autoScroll) {
      _scrollToBottom(parent);
    }
  }

  void print(String line, {bool newline: true}) {
    var span = new SpanElement();
    span.classes.add('normal');
    span.appendText(line);
    if (newline) {
      span.appendText('\n');
    }
    _append(span);
  }

  void printBold(String line, {bool newline: true}) {
    var span = new SpanElement();
    span.classes.add('bold');
    span.appendText(line);
    if (newline) {
      span.appendText('\n');
    }
    _append(span);
  }

  void printRed(String line, {bool newline: true}) {
    var span = new SpanElement();
    span.classes.add('red');
    span.appendText(line);
    if (newline) {
      span.appendText('\n');
    }
    _append(span);
  }

  void printStdio(List<String> lines) {
    bool autoScroll = _isScrolledToBottom(parent);
    for (var line in lines) {
      var span = new SpanElement();
      span.classes.add('green');
      span.appendText(line);
      span.appendText('\n');
      children.add(span);
    }
    if (autoScroll) {
      _scrollToBottom(parent);
    }
  }

  void printRef(
      S.Isolate isolate, S.Instance ref, M.InstanceRepository instances,
      {bool newline: true}) {
    _append(new InstanceRefElement(isolate, ref, instances, queue: app.queue));
    if (newline) {
      this.newline();
    }
  }

  void newline() {
    _append(new BRElement());
  }

  void clear() {
    children.clear();
  }

  void render() {
    /* nothing to do */
  }

  ObservatoryApplication get app => ObservatoryApplication.app;
}

class DebuggerInputElement extends HtmlElement implements Renderable {
  static const tag = const Tag<DebuggerInputElement>('debugger-input');

  S.Isolate _isolate;
  ObservatoryDebugger _debugger;
  bool _busy = false;
  final _modalPromptDiv = new DivElement()..classes = ['modalPrompt', 'hidden'];
  final _textBox = new TextInputElement()
    ..classes = ['textBox']
    ..autofocus = true;
  String get modalPrompt => _modalPromptDiv.text;
  set modalPrompt(String value) {
    if (_modalPromptDiv.text == '') {
      _modalPromptDiv.classes.remove('hidden');
    }
    _modalPromptDiv.text = value;
    if (_modalPromptDiv.text == '') {
      _modalPromptDiv.classes.add('hidden');
    }
  }

  String get text => _textBox.value;
  set text(String value) => _textBox.value = value;
  var modalCallback = null;

  factory DebuggerInputElement(
      S.Isolate isolate, ObservatoryDebugger debugger) {
    final DebuggerInputElement e = document.createElement(tag.name);
    e.children = [e._modalPromptDiv, e._textBox];
    e._textBox.select();
    e._textBox.onKeyDown.listen(e._onKeyDown);
    return e;
  }

  DebuggerInputElement.created() : super.created();

  void _onKeyDown(KeyboardEvent e) {
    if (_busy) {
      e.preventDefault();
      return;
    }
    _busy = true;
    if (modalCallback != null) {
      if (e.keyCode == KeyCode.ENTER) {
        var response = text;
        modalCallback(response).whenComplete(() {
          text = '';
          _busy = false;
        });
      } else {
        _busy = false;
      }
      return;
    }
    switch (e.keyCode) {
      case KeyCode.TAB:
        e.preventDefault();
        int cursorPos = _textBox.selectionStart;
        _debugger.complete(text.substring(0, cursorPos)).then((completion) {
          text = completion + text.substring(cursorPos);
          // TODO(turnidge): Move the cursor to the end of the
          // completion, rather than the end of the string.
        }).whenComplete(() {
          _busy = false;
        });
        break;

      case KeyCode.ENTER:
        var command = text;
        _debugger.run(command).whenComplete(() {
          text = '';
          _busy = false;
        });
        break;

      case KeyCode.UP:
        e.preventDefault();
        text = _debugger.historyPrev(text);
        _busy = false;
        break;

      case KeyCode.DOWN:
        e.preventDefault();
        text = _debugger.historyNext(text);
        _busy = false;
        break;

      case KeyCode.PAGE_UP:
        e.preventDefault();
        try {
          _debugger.upFrame(1);
        } on RangeError catch (_) {
          // Ignore.
        }
        _busy = false;
        break;

      case KeyCode.PAGE_DOWN:
        e.preventDefault();
        try {
          _debugger.downFrame(1);
        } on RangeError catch (_) {
          // Ignore.
        }
        _busy = false;
        break;

      case KeyCode.F7:
        e.preventDefault();
        _debugger.resume().whenComplete(() {
          _busy = false;
        });
        break;

      case KeyCode.F8:
        e.preventDefault();
        _debugger.toggleBreakpoint().whenComplete(() {
          _busy = false;
        });
        break;

      case KeyCode.F9:
        e.preventDefault();
        _debugger.smartNext().whenComplete(() {
          _busy = false;
        });
        break;

      case KeyCode.F10:
        e.preventDefault();
        _debugger.step().whenComplete(() {
          _busy = false;
        });
        break;

      case KeyCode.SEMICOLON:
        if (e.ctrlKey) {
          e.preventDefault();
          _debugger.console.printRed('^;');
          _debugger.pause().whenComplete(() {
            _busy = false;
          });
        } else {
          _busy = false;
        }
        break;

      default:
        _busy = false;
        break;
    }
  }

  void enterMode(String prompt, callback) {
    assert(modalPrompt == null);
    modalPrompt = prompt;
    modalCallback = callback;
  }

  void exitMode() {
    assert(modalPrompt != null);
    modalPrompt = null;
    modalCallback = null;
  }

  void focus() {
    _textBox.focus();
  }

  void render() {
    // Nothing to do.
  }
}

final SvgSvgElement iconExpandLess = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PolygonElement()
      ..setAttribute('points', '12,8 6,14 7.4,15.4 12,10.8 16.6,15.4 18,14 ')
  ];

final SvgSvgElement iconExpandMore = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PolygonElement()
      ..setAttribute('points', '16.6,8.6 12,13.2 7.4,8.6 6,10 12,16 18,10 ')
  ];

final SvgSvgElement iconChevronRight = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PathElement()
      ..setAttribute('d', 'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z')
  ];

final SvgSvgElement iconChevronLeft = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PathElement()
      ..setAttribute('d', 'M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z')
  ];

final SvgSvgElement iconHorizontalThreeDot = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PathElement()
      ..setAttribute(
          'd',
          'M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
          '2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
          '2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
          '2-2-.9-2-2-2z')
  ];

final SvgSvgElement iconVerticalThreeDot = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PathElement()
      ..setAttribute(
          'd',
          'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 '
          '2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
          '2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 '
          '2-.9 2-2-.9-2-2-2z')
  ];

final SvgSvgElement iconInfo = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PathElement()
      ..setAttribute(
          'd',
          'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 '
          '10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z')
  ];

final SvgSvgElement iconInfoOutline = new SvgSvgElement()
  ..setAttribute('width', '24')
  ..setAttribute('height', '24')
  ..children = [
    new PathElement()
      ..setAttribute(
          'd',
          'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 '
          '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 '
          '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 '
          '9h2V7h-2v2z')
  ];
