# 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 logging
import math
import threading

import common
from autotest_lib.client.common_lib import env
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros import retry
from autotest_lib.frontend.afe.json_rpc import proxy
from autotest_lib.server import frontend
try:
    from chromite.lib import retry_util
    from chromite.lib import timeout_util
except ImportError:
    logging.warn('Unable to import chromite.')
    retry_util = None
    timeout_util = None

try:
    from chromite.lib import metrics
except ImportError:
    logging.warn('Unable to import metrics from chromite.')
    metrics = utils.metrics_mock


def convert_timeout_to_retry(backoff, timeout_min, delay_sec):
    """Compute the number of retry attempts for use with chromite.retry_util.

    @param backoff: The exponential backoff factor.
    @param timeout_min: The maximum amount of time (in minutes) to sleep.
    @param delay_sec: The amount to sleep (in seconds) between each attempt.

    @return: The number of retry attempts in the case of exponential backoff.
    """
    # Estimate the max_retry in the case of exponential backoff:
    # => total_sleep = sleep*sum(r=0..max_retry-1, backoff^r)
    # => total_sleep = sleep( (1-backoff^max_retry) / (1-backoff) )
    # => max_retry*ln(backoff) = ln(1-(total_sleep/sleep)*(1-backoff))
    # => max_retry = ln(1-(total_sleep/sleep)*(1-backoff))/ln(backoff)
    total_sleep = timeout_min * 60
    numerator = math.log10(1 - (total_sleep / delay_sec) * (1 - backoff))
    denominator = math.log10(backoff)
    return int(math.ceil(numerator / denominator))


class RetryingAFE(frontend.AFE):
    """Wrapper around frontend.AFE that retries all RPCs.

    Timeout for retries and delay between retries are configurable.
    """
    def __init__(self, timeout_min=30, delay_sec=10, **dargs):
        """Constructor

        @param timeout_min: timeout in minutes until giving up.
        @param delay_sec: pre-jittered delay between retries in seconds.
        """
        self.timeout_min = timeout_min
        self.delay_sec = delay_sec
        super(RetryingAFE, self).__init__(**dargs)


    def set_timeout(self, timeout_min):
        """Set timeout minutes for the AFE server.

        @param timeout_min: The timeout minutes for AFE server.
        """
        self.timeout_min = timeout_min


    def run(self, call, **dargs):
        """Method for running RPC call.

        @param call: A string RPC call.
        @param dargs: the parameters of the RPC call.
        """
        if retry_util is None:
            raise ImportError('Unable to import chromite. Please consider '
                              'running build_externals to build site packages.')
        # exc_retry: We retry if this exception is raised.
        # raiselist: Exceptions that we raise immediately if caught.
        exc_retry = Exception
        raiselist = (ImportError, error.RPCException, proxy.JSONRPCException,
                     timeout_util.TimeoutError, error.ControlFileNotFound)
        backoff = 2
        max_retry = convert_timeout_to_retry(backoff, self.timeout_min,
                                             self.delay_sec)

        def _run(self, call, **dargs):
            return super(RetryingAFE, self).run(call, **dargs)

        def handler(exc):
            """Check if exc is an exc_retry or if it's in raiselist.

            @param exc: An exception.

            @return: True if exc is an exc_retry and is not
                     in raiselist. False otherwise.
            """
            is_exc_to_check = isinstance(exc, exc_retry)
            is_in_raiselist = isinstance(exc, raiselist)
            return is_exc_to_check and not is_in_raiselist

        # If the call is not in main thread, signal can't be used to abort the
        # call. In that case, use a basic retry which does not enforce timeout
        # if the process hangs.
        @retry.retry(Exception, timeout_min=self.timeout_min,
                     delay_sec=self.delay_sec,
                     raiselist=[ImportError, error.RPCException,
                                proxy.ValidationError])
        def _run_in_child_thread(self, call, **dargs):
            return super(RetryingAFE, self).run(call, **dargs)

        if isinstance(threading.current_thread(), threading._MainThread):
            # Set the keyword argument for GenericRetry
            dargs['sleep'] = self.delay_sec
            dargs['backoff_factor'] = backoff
            # timeout_util.Timeout fundamentally relies on sigalrm, and doesn't
            # work at all in wsgi environment (just emits logs spam). So, don't
            # use it in wsgi.
            try:
                if env.IN_MOD_WSGI:
                    return retry_util.GenericRetry(handler, max_retry, _run,
                                                   self, call, **dargs)
                with timeout_util.Timeout(self.timeout_min * 60):
                    return retry_util.GenericRetry(handler, max_retry, _run,
                                                   self, call, **dargs)
            except timeout_util.TimeoutError:
                c = metrics.Counter(
                        'chromeos/autotest/retrying_afe/retry_timeout')
                # Reserve field job_details for future use.
                f = {'destination_server': self.server.split(':')[0],
                     'call': call,
                     'job_details': ''}
                c.increment(fields=f)
                raise
        else:
            return _run_in_child_thread(self, call, **dargs)


class RetryingTKO(frontend.TKO):
    """Wrapper around frontend.TKO that retries all RPCs.

    Timeout for retries and delay between retries are configurable.
    """
    def __init__(self, timeout_min=30, delay_sec=10, **dargs):
        """Constructor

        @param timeout_min: timeout in minutes until giving up.
        @param delay_sec: pre-jittered delay between retries in seconds.
        """
        self.timeout_min = timeout_min
        self.delay_sec = delay_sec
        super(RetryingTKO, self).__init__(**dargs)


    def run(self, call, **dargs):
        """Method for running RPC call.

        @param call: A string RPC call.
        @param dargs: the parameters of the RPC call.
        """
        @retry.retry(Exception, timeout_min=self.timeout_min,
                     delay_sec=self.delay_sec,
                     raiselist=[ImportError, error.RPCException,
                                proxy.ValidationError])
        def _run(self, call, **dargs):
            return super(RetryingTKO, self).run(call, **dargs)
        return _run(self, call, **dargs)
