--[[ $%BEGINLICENSE%$
 Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as
 published by the Free Software Foundation; version 2 of the
 License.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 02110-1301  USA

 $%ENDLICENSE%$ --]]
--[[

   

--]]
local function str2hex(str)
  local raw_len = string.len(str)
  local i = 1
  local o = ""
  while i <= raw_len do
    o = o .. string.format(" %02x", string.byte(str, i))
    i = i + 1
  end

  return o
end

--
-- map the constants to strings 
-- lua starts at 1
local command_names = {
	"COM_SLEEP",
	"COM_QUIT",
	"COM_INIT_DB",
	"COM_QUERY",
	"COM_FIELD_LIST",
	"COM_CREATE_DB",
	"COM_DROP_DB",
	"COM_REFRESH",
	"COM_SHUTDOWN",
	"COM_STATISTICS",
	"COM_PROCESS_INFO",
	"COM_CONNECT",
	"COM_PROCESS_KILL",
	"COM_DEBUG",
	"COM_PING",
	"COM_TIME",
	"COM_DELAYED_INSERT",
	"COM_CHANGE_USER",
	"COM_BINLOG_DUMP",
	"COM_TABLE_DUMP",
	"COM_CONNECT_OUT",
	"COM_REGISTER_SLAVE",
	"COM_STMT_PREPARE",
	"COM_STMT_EXECUTE",
	"COM_STMT_SEND_LONG_DATA",
	"COM_STMT_CLOSE",
	"COM_STMT_RESET",
	"COM_SET_OPTION",
	"COM_STMT_FETCH",
	"COM_DAEMON"
}

--- dump the result-set to stdout
--
-- @param inj "packet.injection"
local function dump_query_result( inj )
  local field_count = 1
  local fields = inj.resultset.fields 

  while fields[field_count] do
    local field = fields[field_count]
    print("| | field[" .. field_count .. "] = { type = " .. 
            field.type .. ", name = " .. field.name .. " }" )
    field_count = field_count + 1
  end

  local row_count = 0
  for row in inj.resultset.rows do
    local cols = {}
    local o
    for i = 1, field_count do
      if not o then
        o = ""
      else 
        o = o .. ", "
      end
      if not row[i] then
        o = o .. "(nul)"
      else
        o = o .. row[i]
      end
    end
    print("| | row["..row_count.."] = { " .. o .. " }")
    row_count = row_count + 1
  end
end

local function decode_query_packet( packet )
  -- we don't have the packet header in the 
  packet_len = string.len(packet)
  

  print("| query.len = " .. packet_len)
  print("| query.packet =" .. str2hex(packet))
  -- print("(decode_query) " .. "| packet-id = " .. "(unknown)")
  
  print("| .--- query")
  print("| | command = " .. command_names[string.byte(packet) + 1])
  if string.byte(packet) == proxy.COM_QUERY then
    -- after the COM_QUERY comes the query
    print("| | query = " .. string.format("%q", string.sub(packet, 2)))
    
  elseif string.byte(packet) == proxy.COM_INIT_DB then
    print("| | db = " .. string.format("%q", string.sub(packet, 2)))
    
  elseif string.byte(packet) == proxy.COM_STMT_PREPARE then
    print("| | query = " .. string.format("%q", string.sub(packet, 2)))
    
  elseif string.byte(packet) == proxy.COM_STMT_EXECUTE then
    local stmt_handler_id = string.byte(packet, 2) + (string.byte(packet, 3) * 256) + (string.byte(packet, 4) * 256 * 256) + (string.byte(packet, 5) * 256 * 256 * 256)
    local flags = string.byte(packet, 6)
    local iteration_count = string.byte(packet, 7) + (string.byte(packet, 8) * 256) + (string.byte(packet, 9) * 256 * 256) + (string.byte(packet, 10) * 256 * 256 * 256)

    print("| | stmt-id = " .. stmt_handler_id )
    print("| | flags = " .. string.format("%02x", flags) )
    print("| | iteration_count = " .. iteration_count )
    
    if packet_len > 10 then
      -- if we don't have any place-holders, no for NUL and friends
      local nul_bitmap = string.byte(packet, 11)
      local new_param  = string.byte(packet, 12)

      print("| | nul_bitmap = " .. string.format("%02x", nul_bitmap ))
      print("| | new_param = " .. new_param )
    else
      print("| | (no params)")
    end
    
    print("| | prepared-query = " .. prepared_queries[stmt_handler_id] )
  else
    print("| | packet =" .. str2hex(packet))
  end
  print("| '---")
end


function read_query()

--[[	for i = 1, #proxy.global.backends do
		local s = proxy.global.backends[i]
		local pool     = s.pool -- we don't have a username yet, try to find a connections which is idling
		local cur_idle = pool.users[""].cur_idle_connections

        print("  [".. i .."].connected_clients = " .. s.connected_clients)
        print("  [".. i .."].idling_connections = " .. cur_idle)
        print("  [".. i .."].type = " .. s.type)
        print("  [".. i .."].state = " .. s.state)
    end
--]]

	proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "SELECT NOW()", { resultset_is_needed = true } )
    if proxy.connection then
        print ("inject monitor query into backend # " .. proxy.connection.backend_ndx)
    else
        print ("inject monitor query")
    end
end

function read_query_result ( inj )

	local res      = assert(inj.resultset)
	local packet   = assert(inj.query)
 
	decode_query_packet(packet)

	print "read query result, dumping"
	dump_query_result(inj)
end
