--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
--   http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--

---- namespace thrift
--thrift = {}
--setmetatable(thrift, {__index = _G}) --> perf hit for accessing global methods
--setfenv(1, thrift)

package.cpath = package.cpath .. ';bin/?.so' -- TODO FIX
function ttype(obj)
  if type(obj) == 'table' and
    obj.__type and
    type(obj.__type) == 'string' then
      return obj.__type
  end
  return type(obj)
end

function terror(e)
  if e and e.__tostring then
    error(e:__tostring())
    return
  end
  error(e)
end

function ttable_size(t)
  local count = 0
  for k, v in pairs(t) do
    count = count + 1
  end
  return count
end

version = '0.12.0'

TType = {
  STOP   = 0,
  VOID   = 1,
  BOOL   = 2,
  BYTE   = 3,
  I08    = 3,
  DOUBLE = 4,
  I16    = 6,
  I32    = 8,
  I64    = 10,
  STRING = 11,
  UTF7   = 11,
  STRUCT = 12,
  MAP    = 13,
  SET    = 14,
  LIST   = 15,
  UTF8   = 16,
  UTF16  = 17
}

TMessageType = {
  CALL  = 1,
  REPLY = 2,
  EXCEPTION = 3,
  ONEWAY = 4
}

-- Recursive __index function to achieve inheritance
function __tobj_index(self, key)
  local v = rawget(self, key)
  if v ~= nil then
    return v
  end

  local p = rawget(self, '__parent')
  if p then
    return __tobj_index(p, key)
  end

  return nil
end

-- Basic Thrift-Lua Object
__TObject = {
  __type = '__TObject',
  __mt = {
    __index = __tobj_index
  }
}
function __TObject:new(init_obj)
  local obj = {}
  if ttype(obj) == 'table' then
    obj = init_obj
  end

  -- Use the __parent key and the __index function to achieve inheritance
  obj.__parent = self
  setmetatable(obj, __TObject.__mt)
  return obj
end

-- Return a string representation of any lua variable
function thrift_print_r(t)
  local ret = ''
  local ltype = type(t)
  if (ltype == 'table') then
    ret = ret .. '{ '
    for key,value in pairs(t) do
      ret = ret .. tostring(key) .. '=' .. thrift_print_r(value) .. ' '
    end
    ret = ret .. '}'
  elseif ltype == 'string' then
    ret = ret .. "'" .. tostring(t) .. "'"
  else
    ret = ret .. tostring(t)
  end
  return ret
end

-- Basic Exception
TException = __TObject:new{
  message,
  errorCode,
  __type = 'TException'
}
function TException:__tostring()
  if self.message then
    return string.format('%s: %s', self.__type, self.message)
  else
    local message
    if self.errorCode and self.__errorCodeToString then
      message = string.format('%d: %s', self.errorCode, self:__errorCodeToString())
    else
      message = thrift_print_r(self)
    end
    return string.format('%s:%s', self.__type, message)
  end
end

TApplicationException = TException:new{
  UNKNOWN                 = 0,
  UNKNOWN_METHOD          = 1,
  INVALID_MESSAGE_TYPE    = 2,
  WRONG_METHOD_NAME       = 3,
  BAD_SEQUENCE_ID         = 4,
  MISSING_RESULT          = 5,
  INTERNAL_ERROR          = 6,
  PROTOCOL_ERROR          = 7,
  INVALID_TRANSFORM       = 8,
  INVALID_PROTOCOL        = 9,
  UNSUPPORTED_CLIENT_TYPE = 10,
  errorCode               = 0,
  __type = 'TApplicationException'
}

function TApplicationException:__errorCodeToString()
  if self.errorCode == self.UNKNOWN_METHOD then
    return 'Unknown method'
  elseif self.errorCode == self.INVALID_MESSAGE_TYPE then
    return 'Invalid message type'
  elseif self.errorCode == self.WRONG_METHOD_NAME then
    return 'Wrong method name'
  elseif self.errorCode == self.BAD_SEQUENCE_ID then
    return 'Bad sequence ID'
  elseif self.errorCode == self.MISSING_RESULT then
    return 'Missing result'
  elseif self.errorCode == self.INTERNAL_ERROR then
    return 'Internal error'
  elseif self.errorCode == self.PROTOCOL_ERROR then
    return 'Protocol error'
  elseif self.errorCode == self.INVALID_TRANSFORM then
    return 'Invalid transform'
  elseif self.errorCode == self.INVALID_PROTOCOL then
    return 'Invalid protocol'
  elseif self.errorCode == self.UNSUPPORTED_CLIENT_TYPE then
    return 'Unsupported client type'
  else
    return 'Default (unknown)'
  end
end

function TException:read(iprot)
  iprot:readStructBegin()
  while true do
    local fname, ftype, fid = iprot:readFieldBegin()
    if ftype == TType.STOP then
      break
    elseif fid == 1 then
      if ftype == TType.STRING then
        self.message = iprot:readString()
      else
        iprot:skip(ftype)
      end
    elseif fid == 2 then
      if ftype == TType.I32 then
        self.errorCode = iprot:readI32()
      else
        iprot:skip(ftype)
      end
    else
      iprot:skip(ftype)
    end
    iprot:readFieldEnd()
  end
  iprot:readStructEnd()
end

function TException:write(oprot)
  oprot:writeStructBegin('TApplicationException')
  if self.message then
    oprot:writeFieldBegin('message', TType.STRING, 1)
    oprot:writeString(self.message)
    oprot:writeFieldEnd()
  end
  if self.errorCode then
    oprot:writeFieldBegin('type', TType.I32, 2)
    oprot:writeI32(self.errorCode)
    oprot:writeFieldEnd()
  end
  oprot:writeFieldStop()
  oprot:writeStructEnd()
end

-- Basic Client (used in generated lua code)
__TClient = __TObject:new{
  __type = '__TClient',
  _seqid = 0
}
function __TClient:new(obj)
  if ttype(obj) ~= 'table' then
    error('TClient must be initialized with a table')
  end

  -- Set iprot & oprot
  if obj.protocol then
    obj.iprot = obj.protocol
    obj.oprot = obj.protocol
    obj.protocol = nil
  elseif not obj.iprot then
    error('You must provide ' .. ttype(self) .. ' with an iprot')
  end
  if not obj.oprot then
    obj.oprot = obj.iprot
  end

  return __TObject.new(self, obj)
end

function __TClient:close()
  self.iprot.trans:close()
  self.oprot.trans:close()
end

-- Basic Processor (used in generated lua code)
__TProcessor = __TObject:new{
  __type = '__TProcessor'
}
function __TProcessor:new(obj)
  if ttype(obj) ~= 'table' then
    error('TProcessor must be initialized with a table')
  end

  -- Ensure a handler is provided
  if not obj.handler then
    error('You must provide ' .. ttype(self) .. ' with a handler')
  end

  return __TObject.new(self, obj)
end
