#!/usr/bin/python3.6
'''
Copyright (C) 2010- Swedish Meteorological and Hydrological Institute (SMHI)

This file is part of RAVE.

RAVE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RAVE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RAVE.  If not, see <http://www.gnu.org/licenses/>.
'''
## RAVE Product Generation Framework XML-RPC server.

## @file
## @author Daniel Michelson, SMHI
## @date 2010-07-08

import sys, os
import traceback
import logging
import multiprocessing, rave_mppool
import rave_pgf_registry, rave_pgf_logger, rave_pgf_qtools
from rave_daemon import Daemon
from rave_defines import PIDFILE, PGF_HOST, PGF_PORT, STDOE, REGFILE, PGFs, LOGLEVEL
from algorithm_runner import algorithm_runner
if sys.version_info < (3,):
  from SimpleXMLRPCServer import SimpleXMLRPCServer
  from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
  from xmlrpclib import ServerProxy
  import xmlrpclib as xmlrpc
else:
  import xmlrpc
  from xmlrpc.server import SimpleXMLRPCServer
  from xmlrpc.server import SimpleXMLRPCRequestHandler
  from xmlrpc.client import ServerProxy


## Stub class for allowing server POSTs only to one place, providing
# rudimentary security.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RAVE',)


## The server that implements the product generation framework in \ref RavePGF.
class rave_pgf_server(Daemon):
  ## Constructor
  # @param host URI to the host for this server.
  # @param port int port number to the host for this server.
  # @param stdin string path to where to direct stdin
  # @param stdout string path to where to direct stdout
  # @param stderr string path to where to direct stderr
  def __init__(self, host=PGF_HOST, port=PGF_PORT, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
    super(rave_pgf_server, self).__init__(PIDFILE, stdin, stdout, stderr)
    self.host = host
    self.port = port

  ## Determines whether the server is running or not.
  def status(self):
      if os.path.isfile(self.pidfile):
          fd = open(self.pidfile)
          c = fd.read()
          fd.close()
          try:
              pgid = os.getpgid(int(c))
              return "running with PID %s and GID %i" % (c[:-1], pgid) 
          except:
              return "not running"
      else:
          return "not running"


  ## Runs the server.
  # Creates an instance of a SimpleXMLRPCServer (from the Python standard
  # library), registers a \ref RavePGF instance, and then serves.
  # Note that the start(), stop(), and restart() methods are inherited from
  # \ref Daemon , but you can call fg() to run the server in the
  # foreground, ie. not daemonize, which is useful for debugging.
  def run(self):
    import atexit
    from rave_pgf import RavePGF
    self.server = SimpleXMLRPCServer((self.host, self.port),
                                     requestHandler=RequestHandler,
                                     allow_none=True)
    
    self.server.register_instance(RavePGF())
    self.server.instance.logger = rave_pgf_logger.rave_pgf_syslog_client()  # Shouldn't be necessary
    self.server.instance.logger.info("%s: Starting PGF server..." % self.server.instance.name)
    self.server.instance._algorithm_registry = rave_pgf_registry.PGF_Registry(filename=REGFILE)
    self.server.instance.queue = rave_pgf_qtools.PGF_JobQueue()
    self.server.instance._load_queue()
    self.server.instance.runner = algorithm_runner(PGFs)
    #self.server.instance.pool = rave_mppool.RavePool(PGFs)
    
    self.server.register_introspection_functions()
    atexit.register(self.server.instance._dump_queue)

    self.server.instance._run_all_jobs()

    self.server.serve_forever()
    

if __name__ == "__main__":
  prog = "rave_pgf"
  usage = "usage: %s start|stop|status|restart|fg" % prog

  if len(sys.argv) != 2:
    print(usage)
    sys.exit()

  ARG = sys.argv[1].lower()

  if ARG not in ('start', 'stop', 'status', 'restart', 'fg'):
    print(usage)
    sys.exit()

  this = rave_pgf_server()

  if ARG == 'stop':
    if os.path.isfile(PIDFILE):
      # Then, dump the job queue via client connection, then stop
      try:
        server = ServerProxy("http://%s:%i/RAVE" % (PGF_HOST, PGF_PORT), verbose=False)
        response = server.flush("Killing me softly")
      except Exception:
        err_msg = traceback.format_exc()
        print("Could not connect to server with error message: %s" % err_msg)
    this.stop()

  if ARG == 'start':
    this.start()

  if ARG == 'restart':
    this.restart()

  if ARG == 'status':
    print("%s is %s" % (prog, this.status()))

  if ARG == 'fg':
    this.run()
