#!/usr/bin/env python
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


'''
This file starts a server for factory shop floor system.

To use it, invoke as a standalone program and assign the shop floor system
module you want to use (modules are located in "shopfloor" subdirectory).

Example:
  ./shopfloor_server -m shopfloor.simple.ShopFloor
'''


import imp
import logging
import optparse
import os
import shopfloor
import SimpleXMLRPCServer


_DEFAULT_SERVER_PORT = 8082
# By default, this server is supposed to serve on same host running omaha
# server, accepting connections from client devices; so the address to bind is
# "all interfaces (0.0.0.0)". For partners running server on clients, they may
# want to change address to "localhost".
_DEFAULT_SERVER_ADDRESS = '0.0.0.0'


def _LoadShopFloorModule(name):
  '''Loads a specified python module.

  Args:
    name: Name of target module, in PACKAGE.MODULE.CLASS format.

  Returns:
    Module reference.
  '''
  (module_path, _, class_name) = name.rpartition('.')
  logging.debug('_LoadShopFloorModule: trying %s.%s', module_path, class_name)
  return getattr(__import__(module_path, fromlist=[class_name]), class_name)


def _RunAsServer(address, port, instance):
  '''Starts a XML-RPC server in given address and port.

  Args:
    address: Address to bind server.
    port: Port for server to listen.
    instance: Server instance for incoming XML RPC requests.

  Returns:
    Never returns if the server is started successfully, otherwise some
    exception will be raised.
  '''
  server = SimpleXMLRPCServer.SimpleXMLRPCServer((address, port),
                                                 allow_none=True,
                                                 logRequests=False)
  server.register_introspection_functions()
  server.register_instance(instance)
  logging.info('Server started: http://%s:%s "%s" version %s',
               address, port, instance.NAME, instance.VERSION)
  server.serve_forever()


def main():
  '''Main entry when being invoked by command line.'''
  parser = optparse.OptionParser()
  parser.add_option('-a', '--address', dest='address', metavar='ADDR',
                    default=_DEFAULT_SERVER_ADDRESS,
                    help='address to bind (default: %default)')
  parser.add_option('-p', '--port', dest='port', metavar='PORT', type='int',
                    default=_DEFAULT_SERVER_PORT,
                    help='port to bind (default: %default)')
  parser.add_option('-m', '--module', dest='module', metavar='MODULE',
                    default='shopfloor.ShopFloorBase',
                    help='shop floor system module to load, in '
                    'PACKAGE.MODULE.CLASS format. Ex: '
                    'shopfloor.simple.ShopFloor')
  parser.add_option('-c', '--config', dest='config', metavar='CONFIG',
                    help='configuration data for shop floor system')
  parser.add_option('-d', '--data-dir', dest='data_dir', metavar='DIR',
                    default=os.path.dirname(os.path.realpath(__file__)),
                    help='data directory for shop floor system')
  parser.add_option('-v', '--verbose', action='count', dest='verbose',
                    help='increase message verbosity')
  parser.add_option('-q', '--quiet', action='store_true', dest='quiet',
                    help='turn off verbose messages')
  (options, args) = parser.parse_args()
  if args:
    parser.error('Invalid args: %s' % ' '.join(args))

  if not options.module:
    parser.error('You need to assign the module to be loaded (-m).')

  verbosity_map = {0: logging.INFO,
                   1: logging.DEBUG}
  verbosity = verbosity_map.get(options.verbose or 0, logging.NOTSET)
  log_format = '%(asctime)s %(levelname)s '
  if options.verbose > 0:
    log_format += '(%(filename)s:%(lineno)d) '
  log_format += '%(message)s'
  logging.basicConfig(level=verbosity, format=log_format)
  if options.quiet:
    logging.disable(logging.INFO)

  try:
    logging.debug('Loading shop floor system module: %s', options.module)
    instance = _LoadShopFloorModule(options.module)()

    if not isinstance(instance, shopfloor.ShopFloorBase):
      logging.critical('Module does not inherit ShopFloorBase: %s',
                       options.module)
      exit(1)

    instance.data_dir = options.data_dir
    instance.config = options.config
    instance._InitBase()
    instance.Init()
  except:
    logging.exception('Failed loading module: %s', options.module)
    exit(1)

  try:
    instance._StartBase()
    logging.debug('Starting RPC server...')
    _RunAsServer(address=options.address, port=options.port, instance=instance)
  finally:
    instance._StopBase()


if __name__ == '__main__':
  main()
