# Copyright 2017 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module to manage stage failure messages."""

import collections
import json
import logging
import re


# Currently, an exception is reported to CIDB failureTabe using the exception
# class name as the exception_type. failure_message_lib.FailureMessageManager
# uses the exception_type to decide which StageFailureMessage class to use
# to rebuild the failure message. Whenever you need to change the names of these
# classes, please add the new class names to their corresponding type lists,
# and DO NOT remove the old class names from the type lists.
# TODO (nxia): instead of using the class name as the exception type when
# reporting an exception to CIDB, we need to have an attribute like
# EXCEPTION_CATEGORY (say EXCEPTION_TYPE) and this type cannot be changed or
# removed from EXCEPTION_TYPE_LIST. But we can add new types to the list.
BUILD_SCRIPT_FAILURE_TYPES = ("BuildScriptFailure",)
PACKAGE_BUILD_FAILURE_TYPES = ("PackageBuildFailure",)


# These keys must exist as column names from failureView in cidb.
FAILURE_KEYS = (
    "id",
    "build_stage_id",
    "outer_failure_id",
    "exception_type",
    "exception_message",
    "exception_category",
    "extra_info",
    "timestamp",
    "stage_name",
    "board",
    "stage_status",
    "build_id",
    "master_build_id",
    "builder_name",
    "build_number",
    "build_config",
    "build_status",
    "important",
    "buildbucket_id",
)


# A namedtuple containing values fetched from CIDB failureView.
_StageFailure = collections.namedtuple("_StageFailure", FAILURE_KEYS)


class StageFailure(_StageFailure):
    """A class presenting values of a failure fetched from CIDB failureView."""

    @classmethod
    def GetStageFailureFromMessage(cls, stage_failure_message):
        """Create StageFailure from a StageFailureMessage instance.

        Args:
            stage_failure_message: An instance of StageFailureMessage.

        Returns:
            An instance of StageFailure.
        """
        return StageFailure(
            stage_failure_message.failure_id,
            stage_failure_message.build_stage_id,
            stage_failure_message.outer_failure_id,
            stage_failure_message.exception_type,
            stage_failure_message.exception_message,
            stage_failure_message.exception_category,
            stage_failure_message.extra_info,
            None,
            stage_failure_message.stage_name,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
        )

    @classmethod
    def GetStageFailureFromDicts(cls, failure_dict, stage_dict, build_dict):
        """Get StageFailure from value dictionaries.

        Args:
            failure_dict: A dict presenting values of a tuple from failureTable.
            stage_dict: A dict presenting values of a tuple from
                buildStageTable.
            build_dict: A dict presenting values of a tuple from buildTable.

        Returns:
            An instance of StageFailure.
        """
        return StageFailure(
            failure_dict["id"],
            failure_dict["build_stage_id"],
            failure_dict["outer_failure_id"],
            failure_dict["exception_type"],
            failure_dict["exception_message"],
            failure_dict["exception_category"],
            failure_dict["extra_info"],
            failure_dict["timestamp"],
            stage_dict["name"],
            stage_dict["board"],
            stage_dict["status"],
            build_dict["id"],
            build_dict["master_build_id"],
            build_dict["builder_name"],
            build_dict["build_number"],
            build_dict["build_config"],
            build_dict["status"],
            build_dict["important"],
            build_dict["buildbucket_id"],
        )


class StageFailureMessage(object):
    """Message class contains information of a general stage failure.

    Failed stages report stage failures to CIDB failureTable (see more details
    in failures_lib.ReportStageFailure). This class constructs a failure
    message instance from the stage failure information stored in CIDB.
    """

    def __init__(self, stage_failure, extra_info=None, stage_prefix_name=None):
        """Construct a StageFailureMessage instance.

        Args:
            stage_failure: An instance of StageFailure.
            extra_info: The extra info of the origin failure, default to None.
            stage_prefix_name: The prefix name (string) of the failed stage,
                default to None.
        """
        self.failure_id = stage_failure.id
        self.build_stage_id = stage_failure.build_stage_id
        self.stage_name = stage_failure.stage_name
        self.exception_type = stage_failure.exception_type
        self.exception_message = stage_failure.exception_message
        self.exception_category = stage_failure.exception_category
        self.outer_failure_id = stage_failure.outer_failure_id

        if extra_info is not None:
            self.extra_info = extra_info
        else:
            # No extra_info provided, decode extra_info from stage_failure.
            self.extra_info = self._DecodeExtraInfo(stage_failure.extra_info)

        if stage_prefix_name is not None:
            self.stage_prefix_name = stage_prefix_name
        else:
            # No stage_prefix_name provided, extra prefix name from
            # stage_failure.
            self.stage_prefix_name = self._ExtractStagePrefixName(
                self.stage_name
            )

    def __str__(self):
        return (
            "[failure id] %s [stage name] %s [stage prefix name] %s "
            "[exception type] %s [exception category] %s [exception message] %s"
            " [extra info] %s"
            % (
                self.failure_id,
                self.stage_name,
                self.stage_prefix_name,
                self.exception_type,
                self.exception_category,
                self.exception_message,
                self.extra_info,
            )
        )

    def _DecodeExtraInfo(self, extra_info):
        """Decode extra info json into dict.

        Args:
            extra_info: The extra_info of the origin exception, default to None.

        Returns:
            An empty dict if extra_info is None; extra_info itself if extra_info
            is a dict; else, load the json string into a dict and return it.
        """
        if not extra_info:
            return {}
        elif isinstance(extra_info, dict):
            return extra_info
        else:
            try:
                return json.loads(extra_info)
            except ValueError as e:
                logging.error("Cannot decode extra_info: %s", e)
                return {}

    # TODO(nxia): Force format checking on stage names when they're created
    def _ExtractStagePrefixName(self, stage_name):
        """Extract stage prefix name given a full stage name.

        Format examples in our current CIDB buildStageTable:
            HWTest [bvt-arc] -> HWTest
            HWTest -> HWTest
            ImageTest -> ImageTest
            ImageTest [amd64-generic] -> ImageTest
            VMTest (attempt 1) -> VMTest
            VMTest [amd64-generic] (attempt 1) -> VMTest

        Args:
            stage_name: The full stage name (string) recorded in CIDB.

        Returns:
            The prefix stage name (string).
        """
        pattern = r"([^ ]+)( +\[([^]]+)\])?( +\(([^)]+)\))?"
        m = re.compile(pattern).match(stage_name)
        if m is not None:
            return m.group(1)
        else:
            return stage_name


class BuildScriptFailureMessage(StageFailureMessage):
    """Message class contains information of a BuildScriptFailure."""

    def GetShortname(self):
        """Return the short name (string) of the run command."""
        return self.extra_info.get("shortname")


class PackageBuildFailureMessage(StageFailureMessage):
    """Message class contains information of a PackagebuildFailure."""

    def GetShortname(self):
        """Return the short name (string) of the run command."""
        return self.extra_info.get("shortname")

    def GetFailedPackages(self):
        """Return a list of packages (strings) that failed to build."""
        return self.extra_info.get("failed_packages", [])


class CompoundFailureMessage(StageFailureMessage):
    """Message class contains information of a CompoundFailureMessage."""

    def __init__(self, stage_failure, **kwargs):
        """Construct a CompoundFailureMessage instance.

        Args:
            stage_failure: An instance of StageFailure.
            **kwargs: Extra message information to pass to StageFailureMessage.
        """
        super().__init__(stage_failure, **kwargs)

        self.inner_failures = []

    def __str__(self):
        msg_str = super().__str__()

        for failure in self.inner_failures:
            msg_str += "(Inner Stage Failure Message) %s" % str(failure)

        return msg_str

    @staticmethod
    def GetFailureMessage(failure_message):
        """Convert a regular failure message instance to CompoundFailureMessage.

        Args:
            failure_message: An instance of StageFailureMessage.

        Returns:
            A CompoundFailureMessage instance.
        """
        return CompoundFailureMessage(
            StageFailure.GetStageFailureFromMessage(failure_message),
            extra_info=failure_message.extra_info,
            stage_prefix_name=failure_message.stage_prefix_name,
        )

    def HasEmptyList(self):
        """Check whether the inner failure list is empty.

        Returns:
            True if self.inner_failures is empty; else, False.
        """
        return not bool(self.inner_failures)

    def HasExceptionCategories(self, exception_categories):
        """Check if any of the inner failures matches the exception categories.

        Args:
            exception_categories: A set of exception categories (members of
                constants.EXCEPTION_CATEGORY_ALL_CATEGORIES).

        Returns:
            True if any of the inner failures matches a member in
            exception_categories; else, False.
        """
        return any(
            x.exception_category in exception_categories
            for x in self.inner_failures
        )

    def MatchesExceptionCategories(self, exception_categories):
        """Check if all the inner failures matches the exception categories.

        Args:
            exception_categories: A set of exception categories (members of
                constants.EXCEPTION_CATEGORY_ALL_CATEGORIES).

        Returns:
            True if all the inner failures match a member in
            exception_categories; else, False.
        """
        return not self.HasEmptyList() and all(
            x.exception_category in exception_categories
            for x in self.inner_failures
        )


class FailureMessageManager(object):
    """Manager class to create a failure message or reconstruct messages."""

    @classmethod
    def CreateMessage(cls, stage_failure, **kwargs):
        """Create a failure message instance depending on the exception type.

        Args:
            stage_failure: An instance of StageFailure.
            **kwargs: Extra message information to pass to StageFailureMessage.

        Returns:
            A failure message instance of StageFailureMessage class (or its
            subclass)
        """
        if stage_failure.exception_type in BUILD_SCRIPT_FAILURE_TYPES:
            return BuildScriptFailureMessage(stage_failure, **kwargs)
        elif stage_failure.exception_type in PACKAGE_BUILD_FAILURE_TYPES:
            return PackageBuildFailureMessage(stage_failure, **kwargs)
        else:
            return StageFailureMessage(stage_failure, **kwargs)

    @classmethod
    def ReconstructMessages(cls, failure_messages):
        """Reconstruct failure messages by nesting messages.

        A failure message with not none outer_failure_id is an inner failure of
        its outer failure message(failure_id == outer_failure_id). This method
        takes a list of failure messages, reconstructs the list by 1) converting
        the outer failure message into a CompoundFailureMessage instance 2)
        insert the inner failure messages to the inner_failures list of their
        outer failure messages.
        CompoundFailures in CIDB aren't nested
        (see failures_lib.ReportStageFailure), so there isn't another
        inner failure list layer in a inner failure message and there are no
        circular dependencies.

        For example, given failure_messages list
          [A(failure_id=1),
           B(failure_id=2, outer_failure_id=1),
           C(failure_id=3, outer_failure_id=1),
           D(failure_id=4),
           E(failure_id=5, outer_failure_id=4),
           F(failure_id=6)]
        this method returns a reconstructed list:
            [
                A(failure_id=1, inner_failures=[
                    B(failure_id=2, outer_failure_id=1),
                    C(failure_id=3, outer_failure_id=1)
                ]),
                D(failure_id=4, inner_failures=[
                    E(failure_id=5, outer_failure_id=4)
                ]),
                F(failure_id=6)
            ]

        Args:
            failure_messages: A list a failure message instances not nested.

        Returns:
            A list of failure message instances of StageFailureMessage class (or
            its subclass). Failure messages with not None outer_failure_id are
            nested into the inner_failures list of their outer failure messages.
        """
        failure_message_dict = {x.failure_id: x for x in failure_messages}

        for failure in failure_messages:
            if failure.outer_failure_id is not None:
                assert failure.outer_failure_id in failure_message_dict
                outer_failure = failure_message_dict[failure.outer_failure_id]
                if not isinstance(outer_failure, CompoundFailureMessage):
                    outer_failure = CompoundFailureMessage.GetFailureMessage(
                        outer_failure
                    )
                    failure_message_dict[
                        outer_failure.failure_id
                    ] = outer_failure

                outer_failure.inner_failures.append(failure)
                del failure_message_dict[failure.failure_id]

        return list(failure_message_dict.values())

    @classmethod
    def ConstructStageFailureMessages(cls, stage_failures):
        """Construct stage failure messages from failure entries from CIDB.

        Args:
            stage_failures: A list of StageFailure instances.

        Returns:
            A list of stage failure message instances of StageFailureMessage
            class (or its subclass). See return type of ReconstructMessages().
        """
        failure_messages = [cls.CreateMessage(f) for f in stage_failures]

        return cls.ReconstructMessages(failure_messages)
