<commit_before>parseString = require('xml2js').parseString
Q = require 'q'
{Emitter, Disposable} = require 'event-kit'
helpers = require '../../helpers.coffee'

DebugContext = require '../../models/debug-context'
Watchpoint = require '../../models/watchpoint'
Breakpoint = require '../../models/breakpoint'

module.exports =
class DbgpInstance extends DebugContext
  constructor: (params) ->
    super
    @socket = params.socket
    @GlobalContext = params.context
    @promises = []
    @socket.on 'data', @stuff
    @emitter = new Emitter
    @buffer = ''
    @GlobalContext.addDebugContext(this)
    @GlobalContext.notifySessionStart()

    @socket.on "error", (error) =>
      @GlobalContext.notifySessionEnd()

  stop: ->
    @socket.end()
    @GlobalContext.notifySessionEnd()

  syncStack: ->
    return @executeCommand('stack_get').then (data) =>
      stackFrames = []
      for frame in data.response.stack
        csonFrame = {
          id:       frame.$.level
          label:    frame.$.where
          filepath: frame.$.filename
          line:     frame.$.lineno
        }
        stackFrames.push csonFrame
      @setStack(stackFrames)

  nextTransactionId: ->
    if !@transaction_id
      @transaction_id = 1
    return @transaction_id++

  parse: (buffer) =>
    while buffer.split("\0").length >= 2
      n = buffer.indexOf("\0")
      len = parseInt(buffer.slice(0, n))
      message = buffer.slice(n+1, n+1+len)
      buffer = buffer.slice(n+2+len)
      if message != ""
        o = parseString message, (err, result) =>
          type = Object.keys(result)[0]
          switch type
            when "init" then @onInit result
            when "response"
              @parseResponse result
    return buffer

  parseResponse: (data) =>
    result = data.response.$
    transactionId = result.transaction_id

    if @promises[transactionId] != undefined
      @promises[transactionId].resolve(data)
      delete @promises[transactionId]
    else
      console.warn "Could not find promise for transaction " + transactionId


  stuff: (data) =>
    message = @parse(data)

  executeCommand: (command, options, data) ->
    @command(command, options, data)

  command: (command, options, data) =>

    transactionId = @nextTransactionId()
    deferred = Q.defer();
    @promises[transactionId] = deferred

    payload = command + " -i " + transactionId
    if options && Object.keys(options).length > 0
      argu = ("-"+(arg) + " " + encodeURI(val) for arg, val of options)
      argu2 = argu.join(" ")
      payload += " " + argu2

    if data
      payload += " -- " + new Buffer(data, 'ascii').toString('base64')
    if @socket
      @socket.write(payload + "\0")
    else
      console.error "No socket found"
    return deferred.promise

  getFeature: (feature_name) =>
    @command("feature_get", {n: feature_name})

  setFeature: (feature_name, value) =>
    return @command("feature_set", {n: feature_name, v: value})

  onInit: (data) =>
    console.log "init"
    @setFeature('show_hidden', 1)
    .then () =>
      return @setFeature('multiple_sessions', 0)
    .then () =>
      return @sendAllBreakpoints()
    .then () =>
      return @executeRun()


  sendAllBreakpoints: =>
    breakpoints = @GlobalContext.getBreakpoints()
    commands = []
    for breakpoint in breakpoints
      commands.push @executeBreakpoint(breakpoint) #@command("breakpoint_set", options)
    return Q.all(commands)

  executeBreakpoint: (breakpoint) =>
    path = breakpoint.getPath()
    path = helpers.localPathToRemote(path)
    options = {
      t: 'line'
      f: 'file://' + path
      n: breakpoint.getLine()
    }
    return @command("breakpoint_set", options)

  continue: (type) =>
    @GlobalContext.notifyRunning()
    return @command(type).then(
      (data) =>
        response = data.response
        switch response.$.status
          when 'break'
            messages = response["xdebug:message"]
            message = messages[0]
            thing = message.$
            filepath = decodeURI(thing['filename']).replace("file:///", "")

            if not filepath.match(/^[a-zA-Z]:/)
              filepath = '/' + filepath

            lineno = thing['lineno']
            breakpoint = new Breakpoint(filepath: filepath, line:lineno)
            @GlobalContext.notifyBreak(breakpoint)
          else
            console.dir response
            console.error "Unhandled status: " + response.$.status
    )

  syncCurrentContext: () ->
    p2 = @getContextNames().then(
      (data) =>
        return @processContextNames(data)
    )

    p3 = p2.then(
      (data) =>
        return @updateWatchpoints(data)
    )

    p4 = p3.then (
      (data) =>
        @syncStack()
    )

    p5 = p4.then(
      (data) =><commit_msg>Properly handle stopping status<commit_after>parseString = require('xml2js').parseString
Q = require 'q'
{Emitter, Disposable} = require 'event-kit'
helpers = require '../../helpers.coffee'

DebugContext = require '../../models/debug-context'
Watchpoint = require '../../models/watchpoint'
Breakpoint = require '../../models/breakpoint'

module.exports =
class DbgpInstance extends DebugContext
  constructor: (params) ->
    super
    @socket = params.socket
    @GlobalContext = params.context
    @promises = []
    @socket.on 'data', @stuff
    @emitter = new Emitter
    @buffer = ''
    @GlobalContext.addDebugContext(this)
    @GlobalContext.notifySessionStart()

    @socket.on "error", (error) =>
      @GlobalContext.notifySessionEnd()

  stop: ->
    @socket.end()
    @GlobalContext.notifySessionEnd()

  syncStack: ->
    return @executeCommand('stack_get').then (data) =>
      stackFrames = []
      for frame in data.response.stack
        csonFrame = {
          id:       frame.$.level
          label:    frame.$.where
          filepath: frame.$.filename
          line:     frame.$.lineno
        }
        stackFrames.push csonFrame
      @setStack(stackFrames)

  nextTransactionId: ->
    if !@transaction_id
      @transaction_id = 1
    return @transaction_id++

  parse: (buffer) =>
    while buffer.split("\0").length >= 2
      n = buffer.indexOf("\0")
      len = parseInt(buffer.slice(0, n))
      message = buffer.slice(n+1, n+1+len)
      buffer = buffer.slice(n+2+len)
      if message != ""
        o = parseString message, (err, result) =>
          type = Object.keys(result)[0]
          switch type
            when "init" then @onInit result
            when "response"
              @parseResponse result
    return buffer

  parseResponse: (data) =>
    result = data.response.$
    transactionId = result.transaction_id

    if @promises[transactionId] != undefined
      @promises[transactionId].resolve(data)
      delete @promises[transactionId]
    else
      console.warn "Could not find promise for transaction " + transactionId


  stuff: (data) =>
    message = @parse(data)

  executeCommand: (command, options, data) ->
    @command(command, options, data)

  command: (command, options, data) =>

    transactionId = @nextTransactionId()
    deferred = Q.defer();
    @promises[transactionId] = deferred

    payload = command + " -i " + transactionId
    if options && Object.keys(options).length > 0
      argu = ("-"+(arg) + " " + encodeURI(val) for arg, val of options)
      argu2 = argu.join(" ")
      payload += " " + argu2

    if data
      payload += " -- " + new Buffer(data, 'ascii').toString('base64')
    if @socket
      @socket.write(payload + "\0")
    else
      console.error "No socket found"
    return deferred.promise

  getFeature: (feature_name) =>
    @command("feature_get", {n: feature_name})

  setFeature: (feature_name, value) =>
    return @command("feature_set", {n: feature_name, v: value})

  onInit: (data) =>
    console.log "init"
    @setFeature('show_hidden', 1)
    .then () =>
      return @setFeature('multiple_sessions', 0)
    .then () =>
      return @sendAllBreakpoints()
    .then () =>
      return @executeRun()


  sendAllBreakpoints: =>
    breakpoints = @GlobalContext.getBreakpoints()
    commands = []
    for breakpoint in breakpoints
      commands.push @executeBreakpoint(breakpoint) #@command("breakpoint_set", options)
    return Q.all(commands)

  executeBreakpoint: (breakpoint) =>
    path = breakpoint.getPath()
    path = helpers.localPathToRemote(path)
    options = {
      t: 'line'
      f: 'file://' + path
      n: breakpoint.getLine()
    }
    return @command("breakpoint_set", options)

  continue: (type) =>
    @GlobalContext.notifyRunning()
    return @command(type).then(
      (data) =>
        response = data.response
        switch response.$.status
          when 'break'
            messages = response["xdebug:message"]
            message = messages[0]
            thing = message.$
            filepath = decodeURI(thing['filename']).replace("file:///", "")

            if not filepath.match(/^[a-zA-Z]:/)
              filepath = '/' + filepath

            lineno = thing['lineno']
            breakpoint = new Breakpoint(filepath: filepath, line:lineno)
            @GlobalContext.notifyBreak(breakpoint)
          when 'stopping'
            @executeStop()
          else
            console.dir response
            console.error "Unhandled status: " + response.$.status
    )

  syncCurrentContext: () ->
    p2 = @getContextNames().then(
      (data) =>
        return @processContextNames(data)
    )

    p3 = p2.then(
      (data) =>
        return @updateWatchpoints(data)
    )

    p4 = p3.then (
      (data) =>
        @syncStack()
    )

    p5 = p4.then(
      (data) =>
{'fraction_non_alphanumeric': 0.13713630201272292, 'fraction_numerical': 0.005422880383773073, 'mean_word_length': 2.4483998561668465, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5200626', 'n_tokens_mistral': 2901, 'n_tokens_neox': 2818, 'n_words': 632}