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

// This test forks a second vm process that runs a dart script as
// a debug target, single stepping through the entire program, and
// recording each breakpoint. At the end, a coverage map of the source
// is printed.
//
// Usage: dart coverage.dart [--wire] [--verbose] target_script.dart
//
//   --wire      see json messages sent between the processes.
//   --verbose   see the stdout and stderr output of the debug
//               target process.

import "dart:convert";
import "dart:io";


// Whether or not to print debug target process on the console.
var showDebuggeeOutput = false;

// Whether or not to print the debugger wire messages on the console.
var verboseWire = false;

var debugger = null;

class Program {
  static int numBps = 0;

  // Maps source code url to source.
  static var sources = new Map<String, Source>();

  // Takes a JSON Debugger response and increments the count for
  // the source position.
  static void recordBp(Map<String,dynamic> msg) {
    // Progress indicator.
    if (++numBps % 1000 == 0) print(numBps);
    var location = msg["params"]["location"];
    if (location == null) return;
    String url = location["url"];
    assert(url != null);
    int libId = location["libraryId"];
    assert(libId != null);
    int tokenPos = location["tokenOffset"];;
    Source s = sources[url];
    if (s == null) {
      debugger.getLineNumberTable(url, libId);
      s = new Source(url);
      sources[url] = s;
    }
    s.recordBp(tokenPos);
  }

  // Prints the annotated source code.
  static void printCoverage() {
    print("Coverage info collected from $numBps breakpoints:");
    for(Source s in sources.values) s.printCoverage();
  }
}


class Source {
  final String url;

  // Maps token position to breakpoint count.
  final tokenCounts = new Map<int,int>();

  // Maps token position to line number.
  final tokenPosToLine = new Map<int,int>();

  Source(this.url);

  void recordBp(int tokenPos) {
    var count = tokenCounts[tokenPos];
    tokenCounts[tokenPos] = count == null ? 1 : count + 1;
  }

  void SetLineInfo(List lineInfoTable) {
    // Each line is encoded as an array with first element being the line
    // number, followed by pairs of (tokenPosition, textOffset).
    lineInfoTable.forEach((List<int> line) {
      int lineNumber = line[0];
      for (int t = 1; t < line.length; t += 2) {
        assert(tokenPosToLine[line[t]] == null);
        tokenPosToLine[line[t]] = lineNumber;
      }
    });
  }

  // Print out the annotated source code. For each line that has seen
  // a breakpoint, print out the maximum breakpoint count for all
  // tokens in the line.
  void printCoverage() {
    var lineCounts = new Map<int,int>();  // BP counts for each line.
    print(url);
    tokenCounts.forEach((tp, bpCount) {
      int lineNumber = tokenPosToLine[tp];
      var lineCount = lineCounts[lineNumber];
      // Remember maximum breakpoint count of all tokens in this line.
      if (lineCount == null || lineCount < bpCount) {
        lineCounts[lineNumber] = bpCount;
      }
    });

    String srcPath = Uri.parse(url).toFilePath();
    List lines = new File(srcPath).readAsLinesSync();
    for (int line = 1; line <= lines.length; line++) {
      String prefix = "      ";
      if (lineCounts.containsKey(line)) {
        prefix = lineCounts[line].toString();
        StringBuffer b = new StringBuffer();
        for (int i = prefix.length; i < 6; i++) b.write(" ");
        b.write(prefix);
        prefix = b.toString();
      }
      print("${prefix}|${lines[line-1]}");
    }
  }
}


class StepCmd {
  Map msg;
  StepCmd(int isolateId) {
    msg = {"id": 0, "command": "stepInto", "params": {"isolateId": isolateId}};
  }
  void handleResponse(Map response) {}
}


class GetLineTableCmd {
  Map msg;
  GetLineTableCmd(int isolateId, int libraryId, String url) {
    msg = { "id": 0,
            "command":  "getLineNumberTable",
            "params": { "isolateId" : isolateId,
                        "libraryId": libraryId,
                        "url": url } };
  }

  void handleResponse(Map response) {
    var url = msg["params"]["url"];
    Source s = Program.sources[url];
    assert(s != null);
    s.SetLineInfo(response["result"]["lines"]);
  }
}


class GetLibrariesCmd {
  Map msg;
  GetLibrariesCmd(int isolateId) {
    msg = { "id": 0,
            "command":  "getLibraries",
            "params": { "isolateId" : isolateId } };
  }

  void handleResponse(Map response) {
    List libs = response["result"]["libraries"];
    for (var lib in libs) {
      String url = lib["url"];
      int libraryId = lib["id"];
      bool enable = !url.startsWith("dart:") && !url.startsWith("package:");
      if (enable) {
        print("Enable stepping for '$url'");
        debugger.enableDebugging(libraryId, true);
      }
    }
  }
}


class SetLibraryPropertiesCmd {
  Map msg;
  SetLibraryPropertiesCmd(int isolateId, int libraryId, bool enableDebugging) {
    // Note that in the debugger protocol, boolean values true and false
    // must be sent as string literals.
    msg = { "id": 0,
            "command":  "setLibraryProperties",
            "params": { "isolateId" : isolateId,
                        "libraryId": libraryId,
                        "debuggingEnabled": "$enableDebugging" } };
  }

  void handleResponse(Map response) {
    // Nothing to do.
  }
}


class Debugger {
  // Debug target process properties.
  Process targetProcess;
  Socket socket;
  bool cleanupDone = false;
  JsonBuffer responses = new JsonBuffer();
  List<String> errors = new List();

  // Data collected from debug target.
  Map currentMessage = null;  // Currently handled message sent by target.
  var outstandingCommand = null;
  var queuedCommands = new List();
  String scriptUrl = null;
  bool shutdownEventSeen = false;
  int isolateId = 0;
  int libraryId = null;

  int nextMessageId = 0;
  bool isPaused = false;
  bool pendingAck = false;

  Debugger(this.targetProcess) {
    var stdoutStringStream = targetProcess.stdout
        .transform(UTF8.decoder)
        .transform(new LineSplitter());
    stdoutStringStream.listen((line) {
      if (showDebuggeeOutput) {
        print("TARG: $line");
      }
      if (line.startsWith("Debugger listening")) {
        RegExp portExpr = new RegExp(r"\d+");
        var port = portExpr.stringMatch(line);
        var pid = targetProcess.pid;
        print("Coverage target process (pid $pid) found "
              "listening on port $port.");
        openConnection(int.parse(port));
      }
    });

    var stderrStringStream = targetProcess.stderr
        .transform(UTF8.decoder)
        .transform(new LineSplitter());
    stderrStringStream.listen((line) {
      if (showDebuggeeOutput) {
        print("TARG: $line");
      }
    });
  }

  // Handle debugger events, updating the debugger state.
  void handleEvent(Map<String,dynamic> msg) {
    if (msg["event"] == "isolate") {
      if (msg["params"]["reason"] == "created") {
        isolateId = msg["params"]["id"];
        assert(isolateId != null);
        print("Debuggee isolate id $isolateId created.");
      } else if (msg["params"]["reason"] == "shutdown") {
        print("Debuggee isolate id ${msg["params"]["id"]} shut down.");
        shutdownEventSeen = true;
      }
    } else if (msg["event"] == "breakpointResolved") {
      var bpId = msg["params"]["breakpointId"];
      assert(bpId != null);
      var isolateId = msg["params"]["isolateId"];
      assert(isolateId != null);
      var location = msg["params"]["location"];
      assert(location != null);
      print("Isolate $isolateId: breakpoint $bpId resolved"
            " at location $location");
      // We may want to maintain a table of breakpoints in the future.
    } else if (msg["event"] == "paused") {
      isPaused = true;
      if (libraryId == null) {
        libraryId = msg["params"]["location"]["libraryId"];
        assert(libraryId != null);
        // This is the first paused event we got. Get all libraries from
        // the debugger so we can turn on debugging events for them.
        getLibraries();
      }
      if (msg["params"]["reason"] == "breakpoint") {
        Program.recordBp(msg);
      }
    } else {
      error("Error: unknown debugger event received");
    }
  }

  // Handle one JSON message object.
  void handleMessage(Map<String,dynamic> receivedMsg) {
    currentMessage = receivedMsg;
    if (receivedMsg["event"] != null) {
      handleEvent(receivedMsg);
      if (errorsDetected) {
        error("Error while handling event message");
        error("Event received from coverage target: $receivedMsg");
      }
    } else if (receivedMsg["id"] != null) {
      // This is a response to the last command we sent.
      int id = receivedMsg["id"];
      assert(outstandingCommand != null);
      assert(outstandingCommand.msg["id"] == id);
      outstandingCommand.handleResponse(receivedMsg);
      outstandingCommand = null;
    } else {
      error("Unexpected message from target");
    }
  }

  // Handle data received over the wire from the coverage target
  // process. Split input from JSON wire format into individual
  // message objects (maps).
  void handleMessages() {
    var msg = responses.getNextMessage();
    while (msg != null) {
      if (verboseWire) print("RECV: $msg");
      if (responses.haveGarbage()) {
        error("Error: leftover text after message: '${responses.buffer}'");
        error("Previous message may be malformed, was: '$msg'");
        cleanup();
        return;
      }
      var msgObj = JSON.decode(msg);
      handleMessage(msgObj);
      if (errorsDetected) {
        error("Error while handling message from coverage target");
        error("Message received from coverage target: $msg");
        cleanup();
        return;
      }
      if (shutdownEventSeen) {
        if (outstandingCommand != null) {
          error("Error: outstanding command when shutdown received");
        }
        cleanup();
        return;
      }
      if (isPaused && (outstandingCommand == null)) {
        var cmd = queuedCommands.length > 0 ? queuedCommands.removeAt(0) : null;
        if (cmd == null) {
          cmd = new StepCmd(isolateId);
          isPaused = false;
        }
        sendMessage(cmd.msg);
        outstandingCommand = cmd;
      }
      msg = responses.getNextMessage();
    }
  }

  // Send a debugger command to the target VM.
  void sendMessage(Map<String,dynamic> msg) {
    assert(msg["id"] != null);
    msg["id"] = nextMessageId++;
    String jsonMsg = JSON.encode(msg);
    if (verboseWire) print("SEND: $jsonMsg");
    socket.write(jsonMsg);
  }

  void getLineNumberTable(String url, int libId) {
    queuedCommands.add(new GetLineTableCmd(isolateId, libId, url));
  }

  void getLibraries() {
    queuedCommands.add(new GetLibrariesCmd(isolateId));
  }

  void enableDebugging(libraryId, enable) {
    queuedCommands.add(new SetLibraryPropertiesCmd(isolateId, libraryId, enable));
  }

  bool get errorsDetected => errors.length > 0;

  // Record error message.
  void error(String s) {
    errors.add(s);
  }

  void openConnection(int portNumber) {
    Socket.connect("127.0.0.1", portNumber).then((s) {
      socket = s;
      socket.setOption(SocketOption.TCP_NODELAY, true);
      var stringStream = socket.transform(UTF8.decoder);
      stringStream.listen(
          (str) {
            try {
              responses.append(str);
              handleMessages();
            } catch(e, trace) {
              print("Unexpected exception:\n$e\n$trace");
              cleanup();
            }
          },
          onDone: () {
            print("Connection closed by coverage target");
            cleanup();
          },
          onError: (e) {
            print("Error '$e' detected in input stream from coverage target");
            cleanup();
          });
      },
      onError: (e) {
        String msg = "Error while connecting to coverage target: $e";
        var trace = getAttachedStackTrace(e);
        if (trace != null) msg += "\nStackTrace: $trace";
        error(msg);
        cleanup();
     });
  }

  void cleanup() {
    if (cleanupDone) return;
    if (socket != null) {
      socket.close().catchError((error) {
        // Print this directly in addition to adding it to the
        // error message queue, in case the error message queue
        // gets printed before this error handler is called.
        print("Error occurred while closing socket: $error");
        error("Error while closing socket: $error");
      });
    }
    var targetPid = targetProcess.pid;
    print("Sending kill signal to process $targetPid.");
    targetProcess.kill();
    // If the process was already dead exitCode is already
    // available and we call exit() in the next event loop cycle.
    // Otherwise this will wait for the process to exit.

    targetProcess.exitCode.then((exitCode) {
      print("Process $targetPid terminated with exit code $exitCode.");
      if (errorsDetected) {
        print("\n===== Errors detected: =====");
        for (int i = 0; i < errors.length; i++) print(errors[i]);
        print("============================\n");
      }
      Program.printCoverage();
      exit(errors.length);
    });
    cleanupDone = true;
  }
}


// Class to buffer wire protocol data from coverage target and
// break it down to individual json messages.
class JsonBuffer {
  String buffer = null;

  append(String s) {
    if (buffer == null || buffer.length == 0) {
      buffer = s;
    } else {
      buffer = buffer + s;
    }
  }

  String getNextMessage() {
    if (buffer == null) return null;
    int msgLen = objectLength();
    if (msgLen == 0) return null;
    String msg = null;
    if (msgLen == buffer.length) {
      msg = buffer;
      buffer = null;
    } else {
      assert(msgLen < buffer.length);
      msg = buffer.substring(0, msgLen);
      buffer = buffer.substring(msgLen);
    }
    return msg;
  }

  bool haveGarbage() {
    if (buffer == null || buffer.length == 0) return false;
    var i = 0, char = " ";
    while (i < buffer.length) {
      char = buffer[i];
      if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
      i++;
    }
    if (i >= buffer.length) {
      return false;
    } else {
      return char != "{";
    }
  }

  // Returns the character length of the next json message in the
  // buffer, or 0 if there is only a partial message in the buffer.
  // The object value must start with '{' and continues to the
  // matching '}'. No attempt is made to otherwise validate the contents
  // as JSON. If it is invalid, a later JSON.decode() will fail.
  int objectLength() {
    int skipWhitespace(int index) {
      while (index < buffer.length) {
        String char = buffer[index];
        if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
        index++;
      }
      return index;
    }
    int skipString(int index) {
      assert(buffer[index - 1] == '"');
      while (index < buffer.length) {
        String char = buffer[index];
        if (char == '"') return index + 1;
        if (char == r'\') index++;
        if (index == buffer.length) return index;
        index++;
      }
      return index;
    }
    int index = 0;
    index = skipWhitespace(index);
    // Bail out if the first non-whitespace character isn't '{'.
    if (index == buffer.length || buffer[index] != '{') return 0;
    int nesting = 0;
    while (index < buffer.length) {
      String char = buffer[index++];
      if (char == '{') {
        nesting++;
      } else if (char == '}') {
        nesting--;
        if (nesting == 0) return index;
      } else if (char == '"') {
        // Strings can contain braces. Skip their content.
        index = skipString(index);
      }
    }
    return 0;
  }
}


void main() {
  var options = new Options();
  var targetOpts = [ "--debug:0" ];
  for (String str in options.arguments) {
    switch (str) {
      case "--verbose":
        showDebuggeeOutput = true;
        break;
      case "--wire":
        verboseWire = true;
        break;
      default:
        targetOpts.add(str);
        break;
    }
  }

  Process.start(options.executable, targetOpts).then((Process process) {
    process.stdin.close();
    debugger = new Debugger(process);
  });
}
