import httplib2
import json

class BigTable():
  def __init__(self, domain='bigtable.appspot.com', port='80', user='', secret_key=''):
    self.url = 'http://' + domain + ':' + port
    self.http = httplib2.Http()
    self.auth = user + ":" + secret_key
  
  def get(self, table, row, column):
    return self._command('GET', 'get', table, row, column)
    
  def getRow(self, table, row):
    return self._command('GET', 'getRow', table, row)
    
  def getRowTs(self, table, row, timestamp):
    return self._command('GET', 'getRowTs', table, row, timestamp)
    
  def getVer(self, table, row, column, count):
    return self._command('GET', 'getVer', table, row, column, count)
    
  def getVerTs(self, table, row, column, timestamp, count):
    return self._command('GET', 'getVerTs', table, row, column, timestamp, count)
    
  def put(self, table, row, column, value):
    parts = (self.url, "put", self.auth, table, row, column)
    (headers, content) = self.http.request('/'.join(parts), "PUT", body=value)
    return self._parse(headers, content)
    
  def putTs(self, table, row, column, timestamp, value):
    parts = (self.url, "putTs", self.auth, table, row, column, timestamp)
    (headers, content) = self.http.request('/'.join(parts), "PUT", body=value)
    return self._parse(headers, content)
    
  def deleteAll(self, table, row, column):
    return self._command('DELETE', 'deleteAll', self.auth, table, row, column)
        
  def deleteAllRow(self, table, row):
    return self._command('DELETE', 'deleteAllRow', self.auth, table, row)
        
  def deleteAllRowTs(self, table, row, timestamp):
    return self._command('DELETE', 'deleteAllRowTs', self.auth, table, row, tiemstamp)
        
  def deleteAllTs(self, table, row, column, timestamp):
    return self._command('DELETE', 'deleteAllTs', self.auth, table, row, column, timestamp)
    
  def _command(self, method, command, *args):
    (headers, content) = self.http.request('/'.join((self.url, command) + args), method)
    return self._parse(headers, content)
    
  def _parse(self, headers, content):
    if headers.status == 200 or headers.status == 201:
      return json.read(content)
    elif headers.status == 400:
      raise BadRequestError(content)
    elif headers.status == 401:
      raise UnauthorizedError(content)
    elif headers.status == 403:
      raise ForbiddenError(content)
    raise UnknownError(content)
    
    
class BigTableError(Exception):    
  def __init__(self, reason):
    self.reason = reason
  def __str__(self):
    return self.reason
    
class BadRequestError(BigTableError): pass    
class UnauthorizedError(BigTableError): pass
class ForbiddenError(BigTableError): pass
class UnknownError(BigTableError): pass

