# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import contextlib
import logging
import time

from mobly import asserts
from mobly import records
from mobly import signals

# When used outside of a `base_test.BaseTestClass` context, such as when using
# the `android_device` controller directly, the `expects.recorder`
# `TestResultRecord` isn't set, which causes `expects` module methods to fail
# from the missing record, so this provides a default, globally accessible
# record for `expects` module to use as well as providing a way to get the
# globally recorded errors.
DEFAULT_TEST_RESULT_RECORD = records.TestResultRecord('mobly', 'global')


class _ExpectErrorRecorder(object):
    """Singleton used to store errors caught via `expect_*` functions in test.

    This class is only instantiated once as a singleton. It holds a reference
    to the record object for the test currently executing.
    """

    def __init__(self, record=None):
        self.reset_internal_states(record=record)

    def reset_internal_states(self, record=None):
        """Resets the internal state of the recorder.

        Args:
            record: records.TestResultRecord, the test record for a test.
        """
        self._record = None
        self._count = 0
        self._record = record

    @property
    def has_error(self):
        """If any error has been recorded since the last reset."""
        return self._count > 0

    @property
    def error_count(self):
        """The number of errors that have been recorded since last reset."""
        return self._count

    def add_error(self, error):
        """Record an error from expect APIs.

        This method generates a position stamp for the expect. The stamp is
        composed of a timestamp and the number of errors recorded so far.

        Args:
            error: Exception or signals.ExceptionRecord, the error to add.
        """
        self._count += 1
        self._record.add_error('expect@%s+%s' % (time.time(), self._count),
                               error)


def expect_true(condition, msg, extras=None):
    """Expects an expression evaluates to True.

    If the expectation is not met, the test is marked as fail after its
    execution finishes.

    Args:
        expr: The expression that is evaluated.
        msg: A string explaining the details in case of failure.
        extras: An optional field for extra information to be included in test
            result.
    """
    try:
        asserts.assert_true(condition, msg, extras)
    except signals.TestSignal as e:
        logging.exception('Expected a `True` value, got `False`.')
        recorder.add_error(e)


def expect_false(condition, msg, extras=None):
    """Expects an expression evaluates to False.

    If the expectation is not met, the test is marked as fail after its
    execution finishes.

    Args:
        expr: The expression that is evaluated.
        msg: A string explaining the details in case of failure.
        extras: An optional field for extra information to be included in test
            result.
    """
    try:
        asserts.assert_false(condition, msg, extras)
    except signals.TestSignal as e:
        logging.exception('Expected a `False` value, got `True`.')
        recorder.add_error(e)


def expect_equal(first, second, msg=None, extras=None):
    """Expects the equality of objects, otherwise fail the test.

    If the expectation is not met, the test is marked as fail after its
    execution finishes.

    Error message is "first != second" by default. Additional explanation can
    be supplied in the message.

    Args:
        first: The first object to compare.
        second: The second object to compare.
        msg: A string that adds additional info about the failure.
        extras: An optional field for extra information to be included in test
            result.
    """
    try:
        asserts.assert_equal(first, second, msg, extras)
    except signals.TestSignal as e:
        logging.exception('Expected %s equals to %s, but they are not.', first,
                          second)
        recorder.add_error(e)


@contextlib.contextmanager
def expect_no_raises(message=None, extras=None):
    """Expects no exception is raised in a context.

    If the expectation is not met, the test is marked as fail after its
    execution finishes.

    A default message is added to the exception `details`.

    Args:
        message: string, custom message to add to exception's `details`.
        extras: An optional field for extra information to be included in test
            result.
    """
    try:
        yield
    except Exception as e:
        e_record = records.ExceptionRecord(e)
        if extras:
            e_record.extras = extras
        msg = message or 'Got an unexpected exception'
        details = '%s: %s' % (msg, e_record.details)
        logging.exception(details)
        e_record.details = details
        recorder.add_error(e_record)


recorder = _ExpectErrorRecorder(DEFAULT_TEST_RESULT_RECORD)
