import email, os, re, smtplib

from autotest_lib.server import frontend

class trigger(object):
    """
    Base trigger class. You are allowed to derive from it and
    override functions to suit your needs in the configuration file.
    """
    def __init__(self):
        self.__actions = []


    def run(self, files):
        # Call each of the actions and pass in the kernel list
        for action in self.__actions:
            action(files)


    def add_action(self, func):
        self.__actions.append(func)


class base_action(object):
    """
    Base class for functor actions. Since actions can also be simple functions
    all action classes need to override __call__ to be callable.
    """
    def __call__(self, kernel_list):
        """
        Perform the action for that given kernel filenames list.

        @param kernel_list: a sequence of kernel filenames (strings)
        """
        raise NotImplementedError('__call__ not implemented')


class map_action(base_action):
    """
    Action that uses a map between machines and their associated control
    files and kernel configuration files and it schedules them using
    the AFE.
    """

    _encode_sep = re.compile('(\D+)')

    class machine_info(object):
        """
        Class to organize the machine associated information for this action.
        """
        def __init__(self, tests, kernel_configs):
            """
            Instantiate a machine_info object.

            @param tests: a sequence of test names (as named in the frontend
                    database) to run for this host
            @param kernel_configs: a dictionary of
                    kernel_version -> config_filename associating kernel
                    versions with corresponding kernel configuration files
                    ("~" inside the filename will be expanded)
            """
            self.tests = tests
            self.kernel_configs = kernel_configs


    def __init__(self, tests_map, jobname_pattern, job_owner='autotest',
                 upload_kernel_config=False):
        """
        Instantiate a map_action.

        @param tests_map: a dictionary of hostname -> machine_info
        @param jobname_pattern: a string pattern used to make the job name
                containing a single "%s" that will be replaced with the kernel
                version
        @param job_owner: the user used to talk with the RPC server
        @param upload_kernel_config: specify if the generate control file
                should contain code that downloads and sends to the client the
                kernel config file (in case it is an URL); this requires that
                the tests_map refers only to server side tests
        """
        self._tests_map = tests_map
        self._jobname_pattern = jobname_pattern
        self._afe = frontend.AFE(user=job_owner)
        self._upload_kernel_config = upload_kernel_config


    def __call__(self, kernel_list):
        """
        Schedule jobs to run on the given list of kernel versions using
        the configured machines -> machine_info mapping for test name
        selection and kernel config file selection.
        """
        for kernel in kernel_list:
            # Get a list of all the machines available for testing
            # and the tests that each one is to execute and group them by
            # test/kernel-config so we can run a single job for the same
            # group

            # dictionary of (test-name,kernel-config)-><list-of-machines>
            jobs = {}
            for machine, info in self._tests_map.iteritems():
                config_paths = info.kernel_configs
                kernel_config = '/boot/config'

                if config_paths:
                    kvers = config_paths.keys()
                    close =  self._closest_kver_leq(kvers, kernel)
                    kernel_config = config_paths[close]

                for test in info.tests:
                    jobs.setdefault((test, kernel_config), [])
                    jobs[(test, kernel_config)].append(machine)

            for (test, kernel_config), hosts in jobs.iteritems():
                c = self._generate_control(test, kernel, kernel_config)
                self._schedule_job(self._jobname_pattern % kernel, c, hosts)


    @classmethod
    def _kver_encode(cls, version):
        """
        Encode the various kernel version strings (ex 2.6.20, 2.6.21-rc1,
        2.7.30-rc2-git3, etc) in a way that makes them easily comparable using
        lexicographic ordering.

        @param version: kernel version string to encode

        @return processed kernel version string that can be compared using
                lexicographic comparison
        """
        # if it's not a "rc" release, add a -rc99 so it orders at the end of
        # all other rc releases for the same base kernel version
        if 'rc' not in version:
            version += '-rc99'

        # if it's not a git snapshot add a -git99 so it orders at the end of
        # all other git snapshots for the same base kernel version
        if 'git' not in version:
            version += '-git99'

        # make all number sequences to be at least 2 in size (with a leading 0
        # if necessary)
        bits = cls._encode_sep.split(version)
        for n in range(0, len(bits), 2):
            if len(bits[n]) < 2:
                bits[n] = '0' + bits[n]
        return ''.join(bits)


    @classmethod
    def _kver_cmp(cls, a, b):
        """
        Compare 2 kernel versions.

        @param a, b: kernel version strings to compare

        @return True if 'a' is less than 'b' or False otherwise
        """
        a, b = cls._kver_encode(a), cls._kver_encode(b)
        return cmp(a, b)


    @classmethod
    def _closest_kver_leq(cls, klist, kver):
        """
        Return the closest kernel ver in the list that is <= kver unless
        kver is the lowest, in which case return the lowest in klist.
        """
        if kver in klist:
            return kver
        l = list(klist)
        l.append(kver)
        l.sort(cmp=cls._kver_cmp)
        i = l.index(kver)
        if i == 0:
            return l[1]
        return l[i - 1]


    def _generate_control(self, test, kernel, kernel_config):
        """
        Uses generate_control_file RPC to generate a control file given
        a test name and kernel information.

        @param test: The test name string as it's named in the frontend
                database.
        @param kernel: A str of the kernel version (i.e. x.x.xx)
        @param kernel_config: A str filename to the kernel config on the
                client

        @returns a dict representing a control file as described by
                frontend.afe.rpc_interface.generate_control_file
        """
        kernel_info = dict(version=kernel,
                           config_file=os.path.expanduser(kernel_config))
        return self._afe.generate_control_file(
                tests=[test], kernel=[kernel_info],
                upload_kernel_config=self._upload_kernel_config)


    def _schedule_job(self, jobname, control, hosts):
        control_type = ('Client', 'Server')[control.is_server]

        self._afe.create_job(control.control_file, jobname,
                             control_type=control_type, hosts=hosts)


class email_action(base_action):
    """
    An action object to send emails about found new kernel versions.
    """
    _MAIL = 'sendmail'

    def __init__(self, dest_addr, from_addr='autotest-server@localhost'):
        """
        Create an email_action instance.

        @param dest_addr: a string or a list of strings with the destination
                email address(es)
        @param from_addr: optional source email address for the sent mails
                (default 'autotest-server@localhost')
        """
        # if passed a string for the dest_addr convert it to a tuple
        if type(dest_addr) is str:
            self._dest_addr = (dest_addr,)
        else:
            self._dest_addr = dest_addr

        self._from_addr = from_addr


    def __call__(self, kernel_list):
        if not kernel_list:
            return

        message = '\n'.join(kernel_list)
        message = 'Testing new kernel releases:\n%s' % message

        self._mail('autotest new kernel notification', message)


    def _mail(self, subject, message_text):
        message = email.Message.Message()
        message['To'] = ', '.join(self._dest_addr)
        message['From'] = self._from_addr
        message['Subject'] = subject
        message.set_payload(message_text)

        if self._sendmail(message.as_string()):
            server = smtplib.SMTP('localhost')
            try:
                server.sendmail(self._from_addr, self._dest_addr,
                                message.as_string())
            finally:
                server.quit()


    @classmethod
    def _sendmail(cls, message):
        """
        Send an email using the sendmail command.
        """
        # open a pipe to the mail program and
        # write the data to the pipe
        p = os.popen('%s -t' % cls._MAIL, 'w')
        p.write(message)
        return p.close()
