--
-- 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.
--

require 'Thrift'
require 'TFramedTransport'
require 'TBinaryProtocol'

-- TServer
TServer = __TObject:new{
  __type = 'TServer'
}

-- 2 possible constructors
--   1. {processor, serverTransport}
--   2. {processor, serverTransport, transportFactory, protocolFactory}
function TServer:new(args)
  if ttype(args) ~= 'table' then
    error('TServer must be initialized with a table')
  end
  if args.processor == nil then
    terror('You must provide ' .. ttype(self) .. ' with a processor')
  end
  if args.serverTransport == nil then
    terror('You must provide ' .. ttype(self) .. ' with a serverTransport')
  end

  -- Create the object
  local obj = __TObject.new(self, args)

  if obj.transportFactory then
    obj.inputTransportFactory = obj.transportFactory
    obj.outputTransportFactory = obj.transportFactory
    obj.transportFactory = nil
  else
    obj.inputTransportFactory = TFramedTransportFactory:new{}
    obj.outputTransportFactory = obj.inputTransportFactory
  end

  if obj.protocolFactory then
    obj.inputProtocolFactory = obj.protocolFactory
    obj.outputProtocolFactory = obj.protocolFactory
    obj.protocolFactory = nil
  else
    obj.inputProtocolFactory = TBinaryProtocolFactory:new{}
    obj.outputProtocolFactory = obj.inputProtocolFactory
  end

  -- Set the __server variable in the handler so we can stop the server
  obj.processor.handler.__server = self

  return obj
end

function TServer:setServerEventHandler(handler)
  self.serverEventHandler = handler
end

function TServer:_clientBegin(content, iprot, oprot)
  if self.serverEventHandler and
    type(self.serverEventHandler.clientBegin) == 'function' then
    self.serverEventHandler:clientBegin(iprot, oprot)
  end
end

function TServer:_preServe()
  if self.serverEventHandler and
    type(self.serverEventHandler.preServe) == 'function' then
    self.serverEventHandler:preServe(self.serverTransport:getSocketInfo())
  end
end

function TServer:_handleException(err)
  if string.find(err, 'TTransportException') == nil then
    print(err)
  end
end

function TServer:serve() end
function TServer:handle(client)
  local itrans, otrans, iprot, oprot, ret, err =
    self.inputTransportFactory:getTransport(client),
    self.outputTransportFactory:getTransport(client),
    self.inputProtocolFactory:getProtocol(client),
    self.outputProtocolFactory:getProtocol(client)

  self:_clientBegin(iprot, oprot)
  while true do
    ret, err = pcall(self.processor.process, self.processor, iprot, oprot)
    if ret == false and err then
      if not string.find(err, "TTransportException") then
        self:_handleException(err)
      end
      break
    end
  end
  itrans:close()
  otrans:close()
end

function TServer:close()
  self.serverTransport:close()
end

-- TSimpleServer
--  Single threaded server that handles one transport (connection)
TSimpleServer = __TObject:new(TServer, {
  __type = 'TSimpleServer',
  __stop = false
})

function TSimpleServer:serve()
  self.serverTransport:listen()
  self:_preServe()
  while not self.__stop do
    client = self.serverTransport:accept()
    self:handle(client)
  end
  self:close()
end

function TSimpleServer:stop()
  self.__stop = true
end
