module DEBUGGER__::DAP_TraceInspector::Custom_Session

def custom_dap_request_event_rdbgTraceInspector(req, result)

def custom_dap_request_event_rdbgTraceInspector(req, result)
  cmd = req.dig('arguments', 'command')
  case cmd
  when 'record'
    process_event_record_cmd(req, result)
  else
    raise "Unknown command #{cmd}"
  end
end

def custom_dap_request_rdbgTraceInspector(req)

def custom_dap_request_rdbgTraceInspector(req)
  cmd = req.dig('arguments', 'command')
  case cmd
  when 'trace'
    process_trace_cmd req
  when 'record'
    process_record_cmd req
  else
    raise "Unknown command #{cmd}"
  end
end

def find_multi_trace

def find_multi_trace
  @tracers.values.each{|t|
    if t.type == 'multi'
      return t
    end
  }
  return nil
end

def process_event_record_cmd(req, result)

def process_event_record_cmd(req, result)
  cmd = req.dig('arguments', 'subCommand')
  case cmd
  when 'enable'
    @ui.respond req, {}
  when 'disable'
    @ui.respond req, {}
  when 'collect'
    cnt = result.delete :dropped_trace_cnt
    if cnt > 0
      @ui.puts "Return #{result[:logs].size} traces and #{cnt} traces are dropped"
    else
      @ui.puts "Return #{result[:logs].size} traces"
    end
    @ui.respond req, result
  else
    raise "Unknown command #{cmd}"
  end
end

def process_record_cmd req

def process_record_cmd req
  cmd = req.dig('arguments', 'subCommand')
  case cmd
  when 'enable'
    @tc << [:dap, :rdbgTraceInspector, req]
  when 'disable'
    @tc << [:dap, :rdbgTraceInspector, req]
  when 'step'
    tid = req.dig('arguments', 'threadId')
    count = req.dig('arguments', 'count')
    if tc = find_waiting_tc(tid)
      @ui.respond req, {}
      tc << [:step, :in, count]
    else
      fail_response req
    end
  when 'stepBack'
    tid = req.dig('arguments', 'threadId')
    count = req.dig('arguments', 'count')
    if tc = find_waiting_tc(tid)
      @ui.respond req, {}
      tc << [:step, :back, count]
    else
      fail_response req
    end
  when 'collect'
    tid = req.dig('arguments', 'threadId')
    if tc = find_waiting_tc(tid)
      tc << [:dap, :rdbgTraceInspector, req]
    else
      fail_response req
    end
  else
    raise "Unknown record sub command #{cmd}"
  end
end

def process_trace_cmd req

def process_trace_cmd req
  cmd = req.dig('arguments', 'subCommand')
  case cmd
  when 'enable'
    events = req.dig('arguments', 'events')
    evts = []
    trace_params = false
    filter = req.dig('arguments', 'filterRegExp')
    max_log_size = req.dig('arguments', 'maxLogSize')
    events.each{|evt|
      case evt
      when 'traceLine'
        evts << :line
      when 'traceCall'
        evts << :call
        evts << :b_call
      when 'traceReturn'
        evts << :return
        evts << :b_return
      when 'traceParams'
        trace_params = true
      when 'traceClanguageCall'
        evts << :c_call
      when 'traceClanguageReturn'
        evts << :c_return
      else
        raise "unknown trace type #{evt}"
      end
    }
    add_tracer MultiTracer.new @ui, evts, trace_params, max_log_size: max_log_size, pattern: filter
    @ui.respond req, {}
  when 'disable'
    if t = find_multi_trace
      t.disable
    end
    @ui.respond req, {}
  when 'collect'
    logs = []
    if t = find_multi_trace
      logs = t.log
      if t.dropped_trace_cnt > 0
        @ui.puts "Return #{logs.size} traces and #{t.dropped_trace_cnt} traces are dropped"
      else
        @ui.puts "Return #{logs.size} traces"
      end
      t.dropped_trace_cnt = 0
    end
    @ui.respond req, logs: logs
  else
    raise "Unknown trace sub command #{cmd}"
  end
  return :retry
end