#!/usr/bin/python3
"""
@copyright
(c) Copyright ESO 2019
All Rights Reserved
ESO (eso.org) is an Intergovernmental Organisation, and therefore special legal conditions apply.
@author Cosylab
"""

import sys
import time
import datetime
import threading
import elt.pymal as mal
from ModCiiSerializationTest.Elt.Error.IcdTest.CiiSerializationTest import CiiSerializationTestSync
from ModCiiSerializationTest.Elt.Error.IcdTest.CiiSerializationTest import CiiSerializationTestSyncService
from ModCiiSerializationTest.Elt.Error.IcdTest.CiiSerializationTest import ServerContextString
from ModCiiSerializableException.Elt.Error.Icd import CiiSerializableException

class CiiInvalidDataTypeException(CiiSerializableException):
  """NOTE: This chould be in elt-common python bindings, not bound yet"""
  pass

EXCEPTION_CALL = 'error'

class CiiSerializationTestServiceImpl:
      """Implementation of the CiiSerializationTestService"""

      def methodWithException(self, param):
          if param == EXCEPTION_CALL:
              raise CiiInvalidDataTypeException(param)
          else:
              return param

      def amiMethodWithException(self, param):
          print('amiMethodWithException, param: ', param)
          serverContext = ServerContextString.getInstance()
          serverAmi = serverContext.createAmi()
          thread = threading.Thread(target=self._amiMethodWithException, args=(param, serverAmi))
          thread.start()
          return serverAmi

      def _amiMethodWithException(self, param, serverAmi):
          print('_amiMethodWithException called, param: ', param)
          if param != EXCEPTION_CALL:
              serverAmi.complete('ONE')
              self._simulateWork()
              serverAmi.complete('TWO')
              self._simulateWork()
              serverAmi.completed('THREE')
          else:
              self._simulateWork()
              serverAmi.complete('ONE')
              self._simulateWork()
              serverAmi.completeExceptionally(CiiInvalidDataTRypeException(param))
          print('_amiMethodWithException, done')

      def _simulateWork(self):
          print('...working...')
          time.sleep(2.0)

def _main():
    """Main function implementation."""
    uri = 'zpb.rr://*:12081/CiiSerializationTest'
    scheme = 'zpb.rr'
    malProperties = {}
    qos = mal.rr.qos.DEFAULT

    # Setup
    malInstance = mal.loadMal('zpb', malProperties)
    ciiFactory = mal.CiiFactory.getInstance()
    ciiFactory.registerMal(scheme, malInstance)

    server = ciiFactory.createServer(uri, 
                                     qos=qos, 
                                     malSpecificProperties=malProperties);
    if server is None:
        raise RuntimeError('Could not create server for uri: %s' % uri)
    serviceImpl = CiiSerializationTestServiceImpl()
    server.registerService('inst_1', CiiSerializationTestSyncService, serviceImpl)
    server.runFor(datetime.timedelta(seconds=60));
    return 0

def main():
    """Wrap main function with exception handler."""
    status = 0
    try:
        status = _main()
    except Exception as e:
         print('FAIL: %s: EXC: %s' % (sys.argv[0], e), file=sys.stderr)
         status = 5
    if status == 0:
        print('PASS')
    return status

if __name__ == '__main__':
    sys.exit(main())
