require 'socket'
require 'mysql'

class SqlBot
  @error = nil
  @has_error = nil
  @rs = nil

  def initialize(hostname, username, password, db)
    @con = Mysql.new(hostname, username, password, db,nil,nil,Mysql::CLIENT_MULTI_STATEMENTS)
    @con.query_with_result=false
  end

  def run_query(query)
    begin
      @rs = @con.query(query)
      @has_error = nil
      @error = nil
    rescue Mysql::Error => e
      @has_error = 1
      @error = e
    ensure

    end
  end

  def use_result()
    return @con.use_result()
  end

  def get_result_set()
    return @rs
  end

  def free_result_set()
    @rs.free()
  end

  def next_result()
    return @con.next_result()
  end

  def has_error()
    return @has_error
  end

  def get_error_string()
    return @error.error()
  end

  def version()
    return @con.get_client_version() 
  end

  def close_conn()
    @con.close
  end
end

class RubyBot
  def initialize(hostname, port, username, password)
    @host = hostname
    @port = port
    @username = username
    @password = password
    @sql_bot = SqlBot.new('localhost','root','purple4','stdw_market')
    @command_hash = { 
      "query" => lambda { 
        |user, args| 
        
        @result = String.new("")
        no_more_results=false

        @sql_bot.run_query(args)

        if ( @sql_bot.has_error )
          @client.puts "@pemit #{user}=#{@sql_bot.get_error_string()}"
        elsif
          until no_more_results
            begin
              @rs = @sql_bot.use_result()
            rescue Mysql::Error => e
              no_more_results = true
            end

            if no_more_results == false
              @rs.each do |row|
                @rs.each_hash |x|
                  @result.concat(x + "|")
                end
                @result.concat("~")
              end
              @rs.free()
              @sql_bot.next_result()
            end
          end

          @client.puts "@pemit #{user}=#{@result}"
        end
      },
      "create_stored_procedure" => lambda {
        |user, args|
        @post_args = args
        @post_args = @post_args.gsub("^","\n\n")
        @sql_bot.run_query(@post_args)

        if ( @sql_bot.has_error ) 
          @client.puts "@pemit #{user}=#{@sql_bot.get_error_string()}"
        end
      },
      "version" => lambda {
        |user, args|
        @client.puts "@pemit #{user}=#{@sql_bot.version()}"
      },
      "quit" => lambda {
        |user, args|
        @sql_bot.close_conn()
        @sql_bot = nil
        @client.close
        @client = nil
        exit()
      }
    }
  end

  def connect()
    @client = TCPSocket.open("#{@host}", "#{@port}")
    @client.puts "connect #{@username} #{@password}"
  end

  def listen_to_game()
    while line = @client.gets
      if ( line =~ /quit/ )
        closeSocket()
      end
      if ( line =~ /<BOT:(.*):(#\d+)>(.*)/ )
        if ( @command_hash.has_key?("#{$1}") )
          @command_hash["#{$1}"].call($2, $3)
        else
          @client.puts "@pemit {#$2}=#-1 INVALID COMMAND '#{$1}'"
        end
      end
    end
  end

  def closeSocket()
    @sql_bot = nil
    @client.close
    @client = nil
    exit()
  end

  def speak(message)
    @client.puts "say #{message}"
  end

  def getConnectInfo()
    puts "Host : #{@host}"
    puts "Port : #{@port}"
    puts "User : #{@username}"
    puts "Pass : #{@password}"
  end
end

bot = RubyBot.new('localhost',4201,'test','blah')

puts "bot id is #{bot.object_id}"

bot.connect()
bot.listen_to_game()

