#!/usr/bin/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.

import atexit
import errno
import logging
import re
import sys
import socket
import threading
import xmlrpclib

import rpm_controller
import rpm_logging_config

from config import rpm_config
from MultiThreadedXMLRPCServer import MultiThreadedXMLRPCServer
from rpm_infrastructure_exception import RPMInfrastructureException

import common
from autotest_lib.site_utils.rpm_control_system import utils

LOG_FILENAME_FORMAT = rpm_config.get('GENERAL','dispatcher_logname_format')


class RPMDispatcher(object):
    """
    This class is the RPM dispatcher server and it is responsible for
    communicating directly to the RPM devices to change a DUT's outlet status.

    When an RPMDispatcher is initialized it registers itself with the frontend
    server, who will field out outlet requests to this dispatcher.

    Once a request is received the dispatcher looks up the RPMController
    instance for the given DUT and then queues up the request and blocks until
    it is processed.

    @var _address: IP address or Hostname of this dispatcher server.
    @var _frontend_server: URI of the frontend server.
    @var _lock: Lock used to synchronize access to _worker_dict.
    @var _port: Port assigned to this server instance.
    @var _worker_dict: Dictionary mapping RPM hostname's to RPMController
                       instances.
    """


    def __init__(self, address, port):
        """
        RPMDispatcher constructor.

        Initialized instance vars and registers this server with the frontend
        server.

        @param address: Address of this dispatcher server.
        @param port: Port assigned to this dispatcher server.

        @raise RPMInfrastructureException: Raised if the dispatch server is
                                           unable to register with the frontend
                                           server.
        """
        self._address = address
        self._port = port
        self._lock = threading.Lock()
        self._worker_dict = {}
        # We assume that the frontend server and dispatchers are running on the
        # same host, and the frontend server is listening for connections from
        # the external world.
        frontend_server_port = rpm_config.getint('RPM_INFRASTRUCTURE',
                                                 'frontend_port')
        self._frontend_server = 'http://%s:%d' % (socket.gethostname(),
                                                  frontend_server_port)
        logging.info('Registering this rpm dispatcher with the frontend '
                     'server at %s.', self._frontend_server)
        client = xmlrpclib.ServerProxy(self._frontend_server)
        # De-register with the frontend when the dispatcher exit's.
        atexit.register(self._unregister)
        try:
            client.register_dispatcher(self._get_serveruri())
        except socket.error as er:
            err_msg = ('Unable to register with frontend server. Error: %s.' %
                       errno.errorcode[er.errno])
            logging.error(err_msg)
            raise RPMInfrastructureException(err_msg)


    def _worker_dict_put(self, key, value):
        """
        Private method used to synchronize access to _worker_dict.

        @param key: key value we are using to access _worker_dict.
        @param value: value we are putting into _worker_dict.
        """
        with self._lock:
            self._worker_dict[key] = value


    def _worker_dict_get(self, key):
        """
        Private method used to synchronize access to _worker_dict.

        @param key: key value we are using to access _worker_dict.
        @return: value found when accessing _worker_dict
        """
        with self._lock:
            return self._worker_dict.get(key)


    def is_up(self):
        """
        Allows the frontend server to see if the dispatcher server is up before
        attempting to queue requests.

        @return: True. If connection fails, the client proxy will throw a socket
                 error on the client side.
        """
        return True


    def queue_request(self, powerunit_info_dict, new_state):
        """
        Looks up the appropriate RPMController instance for the device and queues
        up the request.

        @param powerunit_info_dict: A dictionary, containing the attribute/values
                                    of an unmarshalled PowerUnitInfo instance.
        @param new_state: [ON, OFF, CYCLE] state we want to the change the
                          outlet to.
        @return: True if the attempt to change power state was successful,
                 False otherwise.
        """
        powerunit_info = utils.PowerUnitInfo(**powerunit_info_dict)
        logging.info('Received request to set device: %s to state: %s',
                     powerunit_info.device_hostname, new_state)
        rpm_controller = self._get_rpm_controller(
                powerunit_info.powerunit_hostname,
                powerunit_info.hydra_hostname)
        return rpm_controller.queue_request(powerunit_info, new_state)


    def _get_rpm_controller(self, rpm_hostname, hydra_hostname=None):
        """
        Private method that retreives the appropriate RPMController instance
        for this RPM Hostname or calls _create_rpm_controller it if it does not
        already exist.

        @param rpm_hostname: hostname of the RPM whose RPMController we want.

        @return: RPMController instance responsible for this RPM.
        """
        if not rpm_hostname:
            return None
        rpm_controller = self._worker_dict_get(rpm_hostname)
        if not rpm_controller:
            rpm_controller = self._create_rpm_controller(
                    rpm_hostname, hydra_hostname)
            self._worker_dict_put(rpm_hostname, rpm_controller)
        return rpm_controller


    def _create_rpm_controller(self, rpm_hostname, hydra_hostname):
        """
        Determines the type of RPMController required and initializes it.

        @param rpm_hostname: Hostname of the RPM we need to communicate with.

        @return: RPMController instance responsible for this RPM.
        """
        hostname_elements = rpm_hostname.split('-')
        if hostname_elements[-2] == 'poe':
            # POE switch hostname looks like 'chromeos2-poe-switch1'.
            logging.info('The controller is a Cisco POE switch.')
            return rpm_controller.CiscoPOEController(rpm_hostname)
        else:
            # The device is an RPM.
            rack_id = hostname_elements[-2]
            rpm_typechecker = re.compile('rack[0-9]+[a-z]+')
            if rpm_typechecker.match(rack_id):
                logging.info('RPM is a webpowered device.')
                return rpm_controller.WebPoweredRPMController(rpm_hostname)
            else:
                logging.info('RPM is a Sentry CDU device.')
                return rpm_controller.SentryRPMController(
                        hostname=rpm_hostname,
                        hydra_hostname=hydra_hostname)


    def _get_serveruri(self):
        """
        Formats the _address and _port into a meaningful URI string.

        @return: URI of this dispatch server.
        """
        return 'http://%s:%d' % (self._address, self._port)


    def _unregister(self):
        """
        Tells the frontend server that this dispatch server is shutting down and
        to unregister it.

        Called by atexit.

        @raise RPMInfrastructureException: Raised if the dispatch server is
                                           unable to unregister with the
                                           frontend server.
        """
        logging.info('Dispatch server shutting down. Unregistering with RPM '
                     'frontend server.')
        client = xmlrpclib.ServerProxy(self._frontend_server)
        try:
            client.unregister_dispatcher(self._get_serveruri())
        except socket.error as er:
            err_msg = ('Unable to unregister with frontend server. Error: %s.' %
                       errno.errorcode[er.errno])
            logging.error(err_msg)
            raise RPMInfrastructureException(err_msg)


def launch_server_on_unused_port():
    """
    Looks up an unused port on this host and launches the xmlrpc server.

    Useful for testing by running multiple dispatch servers on the same host.

    @return: server,port - server object and the port that which it is listening
             to.
    """
    address = socket.gethostbyname(socket.gethostname())
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # Set this socket to allow reuse.
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('', 0))
    port = sock.getsockname()[1]
    server = MultiThreadedXMLRPCServer((address, port),
                                       allow_none=True)
    sock.close()
    return server, port


if __name__ == '__main__':
    """
    Main function used to launch the dispatch server. Creates an instance of
    RPMDispatcher and registers it to a MultiThreadedXMLRPCServer instance.
    """
    if len(sys.argv) != 2:
      print 'Usage: ./%s <log_file_name>' % sys.argv[0]
      sys.exit(1)

    rpm_logging_config.start_log_server(sys.argv[1], LOG_FILENAME_FORMAT)
    rpm_logging_config.set_up_logging_to_server()

    # Get the local ip _address and set the server to utilize it.
    address = socket.gethostbyname(socket.gethostname())
    server, port = launch_server_on_unused_port()
    rpm_dispatcher = RPMDispatcher(address, port)
    server.register_instance(rpm_dispatcher)
    server.serve_forever()
