require 'mysql2'
require 'json'

class SQLWrapper
  @@debug = true
  @@socket = nil

  def initialize
    @client = SQLWrapper.client
  end

  def self.socket=(sock)
    @@socket = sock
  end

  def self.quote(string)
    SQLWrapper.new().quote(string)
  end

  def self.escape(string)
    SQLWrapper.new().escape(string)
  end

  def self.build(args)
    SQLWrapper.new().build(args)
  end

  def self.insert(table, fields)
    SQLWrapper.new().insert(table, fields)
  end

  def self.rows(sql)
    SQLWrapper.new().rows(sql)
  end

  def self.query(sql)
    SQLWrapper.new().query(sql)
  end

  def self.select(table, id, id_field="id")
    SQLWrapper.new().select(table, id, id_field)
  end

  def self.debug(bool=true)
    @@debug = bool
  end

  def self.client
    if @@socket.nil?
      return Mysql2::Client.new(
        :host => AltHack::Config[:mysql_host],
        :username => AltHack::Config[:mysql_username],
        :password => AltHack::Config[:mysql_password],
        :database => AltHack::Config[:mysql_database]
      )
    else
      return Mysql2::Client.new(
        :host => AltHack::Config[:mysql_host],
        :username => AltHack::Config[:mysql_username],
        :password => AltHack::Config[:mysql_password],
        :database => AltHack::Config[:mysql_database],
        :socket => @@socket
      )
    end
  end

  def close
    @client.close()
  end

  def quote(string)
    "\'" + escape(string) + "\'"
  end

  def escape(string)
    @client.escape("#{string}")
  end

  def select(table, id, id_field="id")
    sql = "SELECT * from #{table} where #{id_field} = #{self.quote(id)} LIMIT 1"
    rows(sql)[0]
  end

  def build(args)
    # select, where, group, limit, order
    args['select'] = args['select'].nil? ? "" : "select #{args['select']}"
    args['where'] = args['where'].nil? ? "" : "where #{args['where']}"
    args['group'] = args['group'].nil? ? "" : "group by #{args['group']}"
    args['limit'] = args['limit'].nil? ? "" : "limit #{args['limit']}"
    args['order'] = args['order'].nil? ? "" : "order by #{args['order']}"

    sql = "#{args['select']} from #{args['table']} #{args['where']} #{args['group']} #{args['order']} #{args['limit']}"

    puts sql if @@debug

    return sql
  end

  def insert(table, fields)
    k = fields.keys
    f = "(" + k.join(',') + ")"
    v = k.map { |key| fields[key] }
    v = "(" + v.join(',') + ")"

    sql = "INSERT INTO #{table} #{f} VALUES #{v}"

    query(sql)
  end

  def query(sql)
    puts sql if @@debug

    @client.query(sql)
  end

  def last_id
    return @client.last_id
  end

  def rows(sql)
    result = []
    begin
      query(sql).each do |row|
        result.push row
      end
    rescue
      STDERR.puts $!
    end
    return result
  end
end
