// 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:html';
import 'dart:math';
import 'dart:svg';

import 'package:logging/logging.dart';
import 'package:observatory/app.dart';
import 'package:observatory/cli.dart';
import 'package:observatory/debugger.dart';
import 'package:observatory/event.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/service.dart' as S;
import 'package:observatory/repositories.dart' as R;
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';

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

  DebuggerCommand(this.debugger, name, List<Command> 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', <Command>[
          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(<String>[], false);
      commands.sort((a, b) => a.name.compareTo(b.name));
      con.print('List of commands:\n');
      for (DebuggerCommand 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 (DebuggerCommand command in commands) {
        con.printBold(_nameAndAlias(command));
        con.print(command.helpLong);

        var newArgs = <String>[];
        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 (DebuggerCommand 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.toList());
  }

  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', <Command>[]);

  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', <Command>[]) {
    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 if (response is S.Sentinel) {
      debugger.console.print(response.valueAsString);
    } else {
      debugger.console.print('= ', newline: false);
      debugger.console.printRef(debugger.isolate, response, debugger.objects);
    }
  }

  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', <Command>[]);

  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', <Command>[]);

  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', <Command>[]) {
    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', <Command>[]);

  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', <Command>[]) {
    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', <Command>[]) {
    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', <Command>[]);

  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', <Command>[]);

  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', <Command>[]) {
    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 RewindCommand extends DebuggerCommand {
  RewindCommand(Debugger debugger) : super(debugger, 'rewind', <Command>[]);

  Future run(List<String> args) async {
    try {
      int count = 1;
      if (args.length == 1) {
        count = int.parse(args[0]);
      } else if (args.length > 1) {
        debugger.console.print('rewind expects 0 or 1 argument');
        return;
      } else if (count < 1 || count > debugger.stackDepth) {
        debugger.console
            .print('frame must be in range [1..${debugger.stackDepth - 1}]');
        return;
      }
      await debugger.rewind(count);
    } on S.ServerRpcException catch (e) {
      if (e.code == S.ServerRpcException.kCannotResume) {
        debugger.console.printRed(e.data['details']);
      } else {
        rethrow;
      }
    }
  }

  String helpShort = 'Rewind the stack to a previous frame';

  String helpLong = 'Rewind the stack to a previous frame.\n'
      '\n'
      'Syntax: rewind\n'
      '        rewind <count>\n';
}

class ReloadCommand extends DebuggerCommand {
  final M.IsolateRepository _isolates;

  ReloadCommand(Debugger debugger, this._isolates)
      : super(debugger, 'reload', <Command>[]);

  Future run(List<String> args) async {
    try {
      if (args.length > 0) {
        debugger.console.print('reload expects no arguments');
        return;
      }
      if (_isolates.reloadSourcesServices.isEmpty) {
        await _isolates.reloadSources(debugger.isolate);
      } else {
        await _isolates.reloadSources(debugger.isolate,
            service: _isolates.reloadSourcesServices.first);
      }
      debugger.console.print('reload complete');
      await debugger.refreshStack();
    } on S.ServerRpcException catch (e) {
      if (e.code == S.ServerRpcException.kIsolateReloadBarred ||
          e.code == S.ServerRpcException.kIsolateIsReloading) {
        debugger.console.printRed(e.data['details']);
      } else {
        rethrow;
      }
    }
  }

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

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

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

  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', <Command>[]);

  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', <Command>[]);

  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', <Command>[]);

  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
    ],
    'causal-async-stacks': [
      _boolValues,
      _setCausalAsyncStacks,
      (debugger, _) => debugger.saneAsyncStacks
    ],
    'awaiter-stacks': [
      _boolValues,
      _setAwaiterStacks,
      (debugger, _) => debugger.awaiterStacks
    ]
  };

  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}');
  }

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

  static Future _setAwaiterStacks(debugger, name, value) async {
    debugger.awaiterStacks = (value == 'true');
    debugger.refreshStack();
    debugger.console.print('${name} == ${value}');
  }

  Future run(List<String> args) async {
    if (args.length == 0) {
      for (var name in _options.keys) {
        dynamic 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 {
        dynamic 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;
      }
      dynamic validValues = optionInfo[0];
      if (!validValues.contains(value)) {
        debugger.console.print("'${value}' is not in ${validValues}");
        return;
      }
      dynamic 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 = <String>[];
    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', <Command>[]);

  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', <Command>[]);

  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', <Command>[]);

  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<Future> 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', <Command>[]);

  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', <Command>[]);

  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', <Command>[
          new IsolateListCommand(debugger),
          new IsolateNameCommand(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.tryParse(arg);

    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 = <String>[];
    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', <Command>[]);

  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 = <Future>[];
    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', <Command>[]);

  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 InfoCommand extends DebuggerCommand {
  InfoCommand(Debugger debugger)
      : super(debugger, 'info', <Command>[
          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', <Command>[]);

  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', <Command>[
          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', <Command>[]);

  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', <Command>[]);

  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 VmCommand extends DebuggerCommand {
  VmCommand(Debugger debugger)
      : super(debugger, 'vm', <Command>[
          new VmListCommand(debugger),
          new VmNameCommand(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;

  bool get causalAsyncStacks => _causalAsyncStacks;
  void set causalAsyncStacks(bool value) {
    settings.set('causal-async-stacks', value);
    _causalAsyncStacks = value;
  }

  bool _causalAsyncStacks;

  bool get awaiterStacks => _awaiterStacks;
  void set awaiterStacks(bool value) {
    settings.set('awaiter-stacks', value);
    _causalAsyncStacks = value;
  }

  bool _awaiterStacks;

  static const String kAwaiterStackFrames = 'awaiterFrames';
  static const String kAsyncCausalStackFrames = 'asyncCausalFrames';
  static const String kStackFrames = 'frames';

  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 {
    if (awaiterStacks) {
      var awaiterStackFrames = stack[kAwaiterStackFrames];
      if (awaiterStackFrames != null) {
        return awaiterStackFrames.length;
      }
    }
    if (causalAsyncStacks) {
      var asyncCausalStackFrames = stack[kAsyncCausalStackFrames];
      if (asyncCausalStackFrames != null) {
        return asyncCausalStackFrames.length;
      }
    }
    return stack[kStackFrames].length;
  }

  List get stackFrames {
    if (awaiterStacks) {
      var awaiterStackFrames = stack[kAwaiterStackFrames];
      if (awaiterStackFrames != null) {
        return awaiterStackFrames;
      }
    }
    if (causalAsyncStacks) {
      var asyncCausalStackFrames = stack[kAsyncCausalStackFrames];
      if (asyncCausalStackFrames != null) {
        return asyncCausalStackFrames;
      }
    }
    return stack[kStackFrames] ?? [];
  }

  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 ReloadCommand(this, new R.IsolateRepository(this.isolate.vm)),
      new RefreshCommand(this),
      new RewindCommand(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');
    _causalAsyncStacks = settings.get('causal-async-stacks') ?? true;
    _awaiterStacks = settings.get('awaiter-stacks') ?? true;
  }

  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((serviceObject) {
      S.Isolate response = serviceObject;
      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 = <Future>[];
      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, objects);
        } 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:
        S.VM vm = event.owner;
        console.print("VM ${vm.displayName} renamed to '${vm.name}'");
        break;

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

      case S.ServiceEvent.kIsolateExit:
        {
          S.Isolate 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:
        S.Isolate 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) {
      console.printRed('Unable to execute command because the connection '
          'to the VM has been closed');
    }, test: (e) => e is S.NetworkRpcException).catchError((e, s) {
      console.printRed(e.toString());
    }, test: (e) => e is CommandException).catchError((e, s) {
      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 = <Future>[];
        for (var bpt in bpts) {
          pending.add(isolate.removeBreakpoint(bpt));
        }
        await Future.wait(pending);
      }
    }
    return new Future.value(null);
  }

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

  Future asyncNext() async {
    if (isolatePaused()) {
      M.AsyncSuspensionEvent 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);
    }
  }

  Future rewind(int count) {
    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.rewind(count);
    } else {
      console.print('The program must be paused');
      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.ObjectRepository _objects;
  M.ScriptRepository _scripts;
  M.EventRepository _events;

  factory DebuggerPageElement(S.Isolate isolate, M.ObjectRepository objects,
      M.ScriptRepository scripts, M.EventRepository events) {
    assert(isolate != null);
    assert(objects != null);
    assert(scripts != null);
    assert(events != null);
    final DebuggerPageElement e = document.createElement(tag.name);
    final debugger = new ObservatoryDebugger(isolate);
    debugger.page = e;
    debugger.objects = objects;
    e._isolate = isolate;
    e._debugger = debugger;
    e._objects = objects;
    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, _objects, _scripts, _events);
    stackDiv.children = <Element>[stackElement];
    final consoleDiv = new DivElement()
      ..classes = ['console']
      ..children = <Element>[consoleElement];
    final commandElement = new DebuggerInputElement(_isolate, _debugger);
    final commandDiv = new DivElement()
      ..classes = ['commandline']
      ..children = <Element>[commandElement];

    children = <Element>[
      navBar(<Element>[
        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 = <Element>[
          stackDiv,
          new DivElement()
            ..children = <Element>[
              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.ObjectRepository _objects;
  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.ObjectRepository objects,
      M.ScriptRepository scripts,
      M.EventRepository events) {
    assert(isolate != null);
    assert(debugger != null);
    assert(scroller != null);
    assert(objects != null);
    assert(scripts != null);
    assert(events != null);
    final DebuggerStackElement e = document.createElement(tag.name);
    e._isolate = isolate;
    e._debugger = debugger;
    e._scroller = scroller;
    e._objects = objects;
    e._scripts = scripts;
    e._events = events;

    var btnPause;
    var btnRefresh;
    e.children = <Element>[
      e._isSampled = new DivElement()
        ..classes = ['sampledMessage', 'hidden']
        ..children = <Element>[
          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, _objects, _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, _objects, _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;
    if (_debugger.awaiterStacks &&
        (newStack[ObservatoryDebugger.kAwaiterStackFrames] != null)) {
      newFrames = newStack[ObservatoryDebugger.kAwaiterStackFrames];
    } else if (_debugger.causalAsyncStacks &&
        (newStack[ObservatoryDebugger.kAsyncCausalStackFrames] != null)) {
      newFrames = newStack[ObservatoryDebugger.kAsyncCausalStackFrames];
    } else {
      newFrames = newStack[ObservatoryDebugger.kStackFrames];
    }

    // 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<DebuggerFrameElement> _r;

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

  Element _scroller;
  DivElement _varsDiv;
  M.Isolate _isolate;
  S.Frame _frame;
  S.Frame get frame => _frame;
  M.ObjectRepository _objects;
  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) {
    Future load = (_frame.function != null)
        ? _frame.function.load()
        : new Future.value(null);
    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.ObjectRepository objects,
      M.ScriptRepository scripts,
      M.EventRepository events,
      {RenderingQueue queue}) {
    assert(isolate != null);
    assert(frame != null);
    assert(scroller != null);
    assert(objects != null);
    assert(scripts != null);
    assert(events != null);
    final DebuggerFrameElement e = document.createElement(tag.name);
    e._r = new RenderingScheduler<DebuggerFrameElement>(e, queue: queue);
    e._isolate = isolate;
    e._frame = frame;
    e._scroller = scroller;
    e._objects = objects;
    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');
    }
    if ((_frame.kind == M.FrameKind.asyncSuspensionMarker) ||
        (_frame.kind == M.FrameKind.asyncCausal)) {
      classes.add('causalFrame');
    }
    if (_frame.kind == M.FrameKind.asyncSuspensionMarker) {
      final content = <Element>[
        new SpanElement()..children = _createMarkerHeader(_frame.marker)
      ];
      children = content;
      return;
    }
    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 = <Element>[
            new DivElement()
              ..classes = ['flex-row-wrap']
              ..children = <Element>[
                new DivElement()
                  ..classes = ['flex-item-script']
                  ..children = _frame.function?.location == null
                      ? const []
                      : [
                          new SourceInsetElement(
                              _isolate,
                              _frame.function.location,
                              _scripts,
                              _objects,
                              _events,
                              currentPos: _frame.location.tokenPos,
                              variables: _frame.variables,
                              inDebuggerContext: true,
                              queue: _r.queue)
                        ],
                new DivElement()
                  ..classes = ['flex-item-vars']
                  ..children = <Element>[
                    _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 = <Element>[
                                      anyRef(_isolate, homeMethod.dartOwner,
                                          _objects,
                                          queue: _r.queue)
                                    ]
                                ]
                      ]..addAll(_frame.variables
                          .map<Element>((v) => new DivElement()
                            ..classes = ['memberItem']
                            ..children = <Element>[
                              new DivElement()
                                ..classes = ['memberName']
                                ..text = v.name,
                              new DivElement()
                                ..classes = ['memberName']
                                ..children = <Element>[
                                  anyRef(_isolate, v['value'], _objects,
                                      queue: _r.queue)
                                ]
                            ])
                          .toList()))
                  ]
              ],
            new DivElement()
              ..classes = ['frameContractor']
              ..children = <Element>[
                collapseButton = new ButtonElement()
                  ..onClick.listen((e) async {
                    collapseButton.disabled = true;
                    await _toggleExpand();
                    collapseButton.disabled = false;
                  })
                  ..children = <Element>[iconExpandLess.clone(true)]
              ]
          ]
      ]);
    }
    children = content;
  }

  List<Element> _createMarkerHeader(String marker) {
    final content = <Element>[
      new DivElement()
        ..classes = ['frameSummaryText']
        ..children = <Element>[
          new DivElement()
            ..classes = ['frameId']
            ..text = 'Frame ${_frame.index}',
          new SpanElement()..text = '$marker',
        ]
    ];
    return [
      new DivElement()
        ..classes = ['frameSummary']
        ..children = content
    ];
  }

  List<Element> _createHeader() {
    final content = <Element>[
      new DivElement()
        ..classes = ['frameSummaryText']
        ..children = <Element>[
          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 = <Element>[iconExpandMore.clone(true)]);
    }
    return [
      new DivElement()
        ..classes = ['frameSummary']
        ..children = content
    ];
  }

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

  bool matchFrame(S.Frame newFrame) {
    if (newFrame.kind != _frame.kind) {
      return false;
    }
    if (newFrame.function == null) {
      return frame.function == null;
    }
    return (newFrame.function.id == _frame.function.id &&
        newFrame.location.script.id == frame.location.script.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.ObjectRepository _objects;
  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.ObjectRepository objects,
      M.ScriptRepository scripts,
      M.EventRepository events,
      {RenderingQueue queue}) {
    assert(isolate != null);
    assert(message != null);
    assert(objects != null);
    assert(events != null);
    final DebuggerMessageElement e = document.createElement(tag.name);
    e._r = new RenderingScheduler<DebuggerMessageElement>(e, queue: queue);
    e._isolate = isolate;
    e._message = message;
    e._objects = objects;
    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 = <Element>[
            new DivElement()
              ..classes = ['flex-row-wrap']
              ..children = <Element>[
                new DivElement()
                  ..classes = ['flex-item-script']
                  ..children = _message.handler == null
                      ? const []
                      : [
                          new SourceInsetElement(
                              _isolate,
                              _message.handler.location,
                              _scripts,
                              _objects,
                              _events,
                              inDebuggerContext: true,
                              queue: _r.queue)
                        ],
                new DivElement()
                  ..classes = ['flex-item-vars']
                  ..children = <Element>[
                    new DivElement()
                      ..classes = ['memberItem']
                      ..children = <Element>[
                        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, _objects,
                                      queue: _r.queue)
                                ]))
                      ]
                  ]
              ],
            new DivElement()
              ..classes = ['messageContractor']
              ..children = <Element>[
                collapseButton = new ButtonElement()
                  ..onClick.listen((e) async {
                    collapseButton.disabled = true;
                    await _toggleExpand();
                    collapseButton.disabled = false;
                  })
                  ..children = <Element>[iconExpandLess.clone(true)]
              ]
          ]
      ]);
    }
    children = content;
  }

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

  List<Element> _createHeader() {
    final content = <Element>[
      new DivElement()
        ..classes = ['messageSummaryText']
        ..children = <Element>[
          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 = <Element>[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 = <Element>[];
  }

  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 = <Element>[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.ObjectRepository objects,
      {bool newline: true}) {
    _append(new InstanceRefElement(isolate, ref, objects, 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 = <Element>[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 = <Element>[
    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 = <Element>[
    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 = <Element>[
    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 = <Element>[
    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 = <Element>[
    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 = <Element>[
    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 = <Element>[
    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 = <Element>[
    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')
  ];
