#!/usr/bin/python2
#
# Copyright 2010 Google Inc. All Rights Reserved.

import logging
import optparse
import pickle
import signal
from SimpleXMLRPCServer import SimpleXMLRPCServer
import sys

from automation.common import logger
from automation.common.command_executer import CommandExecuter
from automation.server import machine_manager
from automation.server.job_group_manager import JobGroupManager
from automation.server.job_manager import JobManager


class Server(object):
  """Plays a role of external interface accessible over XMLRPC."""

  def __init__(self, machines_file=None, dry_run=False):
    """Default constructor.

    Args:
      machines_file: Path to file storing a list of machines.
      dry_run: If True, the server only simulates command execution.
    """
    CommandExecuter.Configure(dry_run)

    self.job_manager = JobManager(
        machine_manager.MachineManager.FromMachineListFile(
            machines_file or machine_manager.DEFAULT_MACHINES_FILE))

    self.job_group_manager = JobGroupManager(self.job_manager)

    self._logger = logging.getLogger(self.__class__.__name__)

  def ExecuteJobGroup(self, job_group, dry_run=False):
    job_group = pickle.loads(job_group)
    self._logger.info('Received ExecuteJobGroup(%r, dry_run=%s) request.',
                      job_group, dry_run)

    for job in job_group.jobs:
      job.dry_run = dry_run
    return self.job_group_manager.AddJobGroup(job_group)

  def GetAllJobGroups(self):
    self._logger.info('Received GetAllJobGroups() request.')
    return pickle.dumps(self.job_group_manager.GetAllJobGroups())

  def KillJobGroup(self, job_group_id):
    self._logger.info('Received KillJobGroup(%d) request.', job_group_id)
    self.job_group_manager.KillJobGroup(pickle.loads(job_group_id))

  def GetJobGroup(self, job_group_id):
    self._logger.info('Received GetJobGroup(%d) request.', job_group_id)

    return pickle.dumps(self.job_group_manager.GetJobGroup(job_group_id))

  def GetJob(self, job_id):
    self._logger.info('Received GetJob(%d) request.', job_id)

    return pickle.dumps(self.job_manager.GetJob(job_id))

  def GetMachineList(self):
    self._logger.info('Received GetMachineList() request.')

    return pickle.dumps(self.job_manager.machine_manager.GetMachineList())

  def StartServer(self):
    self.job_manager.StartJobManager()

  def StopServer(self):
    self.job_manager.StopJobManager()
    self.job_manager.join()


def GetServerOptions():
  """Get server's settings from command line options."""
  parser = optparse.OptionParser()
  parser.add_option('-m',
                    '--machines-file',
                    dest='machines_file',
                    help='The location of the file '
                    'containing the machines database',
                    default=machine_manager.DEFAULT_MACHINES_FILE)
  parser.add_option('-n',
                    '--dry-run',
                    dest='dry_run',
                    help='Start the server in dry-run mode, where jobs will '
                    'not actually be executed.',
                    action='store_true',
                    default=False)
  return parser.parse_args()[0]


def Main():
  logger.SetUpRootLogger(filename='server.log', level=logging.DEBUG)

  options = GetServerOptions()
  server = Server(options.machines_file, options.dry_run)
  server.StartServer()

  def _HandleKeyboardInterrupt(*_):
    server.StopServer()
    sys.exit(1)

  signal.signal(signal.SIGINT, _HandleKeyboardInterrupt)

  try:
    xmlserver = SimpleXMLRPCServer(
        ('localhost', 8000),
        allow_none=True,
        logRequests=False)
    xmlserver.register_instance(server)
    xmlserver.serve_forever()
  except Exception as ex:
    logging.error(ex)
    server.StopServer()
    sys.exit(1)


if __name__ == '__main__':
  Main()
