
import json
import termcolor
import collections
import copy
import abc
from six import with_metaclass

import wavefront_api_client


from .Resource import Resource

# To print a human readable string for the class type name


class Meta(abc.ABCMeta):
    def __str__(self):
        return "alert"


class Alert(with_metaclass(Meta, Resource)):
    """ A class representing an Alert"""

    def __str__(self):
        s = self.summaryTableRow(False)
        return s

    __repr__ = __str__

    # Some fields in alerts are not interesting. Omit displaying and saving
    # them.
    _omittedFields = set([
        "activeMaintenanceWindows",
        "alertsLastDay",
        "alertsLastMonth",
        "alertsLastWeek",
        "conditionQBEnabled",
        "created",
        "createdEpochMillis",
        "createUserId",
        "creatorId",
        "deleted",
        "displayExpressionQBEnabled",
        "endTime",
        "event",
        "failingHostLabelPairs",
        "hostsUsed",
        "includeObsoleteMetrics",
        "inMaintenanceHostLabelPairs",
        "inTrash",
        "lastEventTime",
        "lastNotificationMillis",
        "lastProcessedMillis",
        "metricsUsed",
        "notificants",
        "pointsScannedAtLastQuery",
        "prefiringHostLabelPairs",
        "processRateMinutes",
        "queryFailing",
        "runningState",
        "runninState",
        "sortAttr",
        "startTime",
        "status",
        "targetInfo",
        "updated",
        "updatedEpochMillis",
        "updaterId",
        "updateUserId",
    ])

    # The command line options used to narrow down Alert resources.
    _supportedFilters = {
        "id": "i",
        "name": "n",
        "condition": "d",
        "displayExpression": "x",
        "additionalInformation": "f",
        "status": "a",
        "severity": "e",
    }

    # TODO : Should we add SNOOZED Until ?
    # This will make it more similar to the wavefront web page.
    _summaryTableKeys = ["id", "name", "status", "severity"]

    _uniqueKey = "id"

    @staticmethod
    def _colorStatus(v):
        """ The value is for the status field in alert data. Return its
        tty colored string accordingly"""

        if v == "CHECKING":
            return termcolor.colored(v, color="green")
        elif v == "ACTIVE" or v == "FIRING":
            return termcolor.colored(v, color="red")
        elif v == "SNOOZED":
            return termcolor.colored(v, color="grey")
        else:
            return v

    @staticmethod
    def _colorSeverity(v):
        """ The value is for the severity a field in alert data. Return its
        tty colored string accordingly"""
        if v == "SEVERE":
            return termcolor.colored(v, color="red")
        elif v == "WARN":
            return termcolor.colored(v, color="yellow")
        elif v == "INFO":
            return termcolor.colored(v, color="blue")
        elif v == "SMOKE":
            return termcolor.colored(v, color="grey")
        else:
            return v

    _coloredKeys = ["status", "severity"]

    @staticmethod
    def _maybeColor(k, v, enableColor):
        """ Depending on the key and the color setting from the command line
        we may want to color the output. This function returns the colored version
        of v if desired or if possible"""

        if not enableColor:
            return v

        # We only color-code alert states and severity information. Nothing else.
        # This is similar to the wavefront webpage interface.
        if k == "status":
            return Alert._colorStatus(v)
        elif k == "severity":
            return Alert._colorSeverity(v)
        else:
            return v

    @staticmethod
    def _formatValueForSummaryTable(k, v, enableColor):
        """Format the given value for a nice print in the summary table  """
        if isinstance(v, collections.MutableSequence):
            return " ".join([Alert._maybeColor(k, x, enableColor) for x in v])
        else:
            return Alert._maybeColor(k, v, enableColor)

    @staticmethod
    def getFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to get all
        alerts from the wavefront Api server"""
        api = wavefront_api_client.SearchApi(wavefrontClient)
        f = api.search_alert_entities
        return f

    @staticmethod
    def getDeletedFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to get all
        deleted alerts from the wavefront Api server"""
        api = wavefront_api_client.SearchApi(wavefrontClient)
        f = api.search_alert_deleted_entities
        return f

    @staticmethod
    def updateFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to update
        one alert in wavefront api server"""
        api = wavefront_api_client.AlertApi(wavefrontClient)
        f = api.update_alert
        return f

    @staticmethod
    def createFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to create
        one new alert in wavefront api server"""
        api = wavefront_api_client.AlertApi(wavefrontClient)
        f = api.create_alert
        return f

    @staticmethod
    def fileExtension():
        """Return the extension used for the file on disc representing this
        resource"""
        return ".alert"

    def __init__(self, state):
        super(Alert, self).__init__(state)

        # Save a reference of self to the static global list.
        self.allRsrcs.append(self)

    @classmethod
    def fromDict(cls, dict):
        """Create a Dashboard object from the given dict dictionary"""
        return cls(dict)

    def uniqueId(self):
        """Return a unique id representing this Alert.
        It is the id field assigned by the wavefront api server"""
        return self._state[Alert._uniqueKey]

    def browserUrlSuffix(self):
        return "/alert/" + str(self.uniqueId())

    def summaryTableRow(self, enableColor):
        # Return the one line summary string. This string becomes the row in the
        # summary table representing this alert.

        fmt = self._summaryTableRowFormat(enableColor)
        row = fmt.format(
            **{k: Alert._formatValueForSummaryTable(k, self._state.get(k, ""),
                                                    enableColor) for k in Alert._summaryTableKeys})
        return row


import json
import termcolor
import collections
import copy
import abc
from six import with_metaclass

import wavefront_api_client


from .Resource import Resource

# To print a human readable string for the class type name


class Meta(abc.ABCMeta):
    def __str__(self):
        return "alert"


class Alert(with_metaclass(Meta, Resource)):
    """ A class representing an Alert"""

    def __str__(self):
        s = self.summaryTableRow(False)
        return s

    __repr__ = __str__

    # Some fields in alerts are not interesting. Omit displaying and saving
    # them.
    _omittedFields = set([
        "activeMaintenanceWindows",
        "alertsLastDay",
        "alertsLastMonth",
        "alertsLastWeek",
        "conditionQBEnabled",
        "created",
        "createdEpochMillis",
        "createUserId",
        "creatorId",
        "deleted",
        "displayExpressionQBEnabled",
        "endTime",
        "event",
        "failingHostLabelPairs",
        "hostsUsed",
        "includeObsoleteMetrics",
        "inMaintenanceHostLabelPairs",
        "inTrash",
        "lastEventTime",
        "lastNotificationMillis",
        "lastProcessedMillis",
        "metricsUsed",
        "notificants",
        "pointsScannedAtLastQuery",
        "prefiringHostLabelPairs",
        "processRateMinutes",
        "queryFailing",
        "runningState",
        "runninState",
        "sortAttr",
        "startTime",
        "status",
        "targetInfo",
        "updated",
        "updatedEpochMillis",
        "updaterId",
        "updateUserId",
    ])

    # The command line options used to narrow down Alert resources.
    _supportedFilters = {
        "id": "i",
        "name": "n",
        "condition": "d",
        "displayExpression": "x",
        "additionalInformation": "f",
        "status": "a",
        "severity": "e",
    }

    # TODO : Should we add SNOOZED Until ?
    # This will make it more similar to the wavefront web page.
    _summaryTableKeys = ["id", "name", "status", "severity"]

    _uniqueKey = "id"

    @staticmethod
    def _colorStatus(v):
        """ The value is for the status field in alert data. Return its
        tty colored string accordingly"""

        if v == "CHECKING":
            return termcolor.colored(v, color="green")
        elif v == "ACTIVE" or v == "FIRING":
            return termcolor.colored(v, color="red")
        elif v == "SNOOZED":
            return termcolor.colored(v, color="grey")
        else:
            return v

    @staticmethod
    def _colorSeverity(v):
        """ The value is for the severity a field in alert data. Return its
        tty colored string accordingly"""
        if v == "SEVERE":
            return termcolor.colored(v, color="red")
        elif v == "WARN":
            return termcolor.colored(v, color="yellow")
        elif v == "INFO":
            return termcolor.colored(v, color="blue")
        elif v == "SMOKE":
            return termcolor.colored(v, color="grey")
        else:
            return v

    _coloredKeys = ["status", "severity"]

    @staticmethod
    def _maybeColor(k, v, enableColor):
        """ Depending on the key and the color setting from the command line
        we may want to color the output. This function returns the colored version
        of v if desired or if possible"""

        if not enableColor:
            return v

        # We only color-code alert states and severity information. Nothing else.
        # This is similar to the wavefront webpage interface.
        if k == "status":
            return Alert._colorStatus(v)
        elif k == "severity":
            return Alert._colorSeverity(v)
        else:
            return v

    @staticmethod
    def _formatValueForSummaryTable(k, v, enableColor):
        """Format the given value for a nice print in the summary table  """
        if isinstance(v, collections.MutableSequence):
            return " ".join([Alert._maybeColor(k, x, enableColor) for x in v])
        else:
            return Alert._maybeColor(k, v, enableColor)

    @staticmethod
    def getFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to get all
        alerts from the wavefront Api server"""
        api = wavefront_api_client.SearchApi(wavefrontClient)
        f = api.search_alert_entities
        return f

    @staticmethod
    def getDeletedFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to get all
        deleted alerts from the wavefront Api server"""
        api = wavefront_api_client.SearchApi(wavefrontClient)
        f = api.search_alert_deleted_entities
        return f

    @staticmethod
    def updateFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to update
        one alert in wavefront api server"""
        api = wavefront_api_client.AlertApi(wavefrontClient)
        f = api.update_alert
        return f

    @staticmethod
    def createFunction(wavefrontClient):
        """Given a wavefrontClient object return the function to call to create
        one new alert in wavefront api server"""
        api = wavefront_api_client.AlertApi(wavefrontClient)
        f = api.create_alert
        return f

    @staticmethod
    def fileExtension():
        """Return the extension used for the file on disc representing this
        resource"""
        return ".alert"

    def __init__(self, state):
        super(Alert, self).__init__(state)

        # Save a reference of self to the static global list.
        self.allRsrcs.append(self)

    @classmethod
    def fromDict(cls, dict):
        """Create a Dashboard object from the given dict dictionary"""
        return cls(dict)

    def uniqueId(self):
        """Return a unique id representing this Alert.
        It is the id field assigned by the wavefront api server"""
        return self._state[Alert._uniqueKey]

    def browserUrlSuffix(self):
        return "/alert/" + str(self.uniqueId())

    def summaryTableRow(self, enableColor):
        # Return the one line summary string. This string becomes the row in the
        # summary table representing this alert.

        fmt = self._summaryTableRowFormat(enableColor)
        row = fmt.format(
            **{k: Alert._formatValueForSummaryTable(k, self._state.get(k, ""),
                                                    enableColor) for k in Alert._summaryTableKeys})
        return row

# To print a human readable string for the class type name A class representing an Alert # Some fields in alerts are not interesting. Omit displaying and saving # them. # The command line options used to narrow down Alert resources. # TODO : Should we add SNOOZED Until ? # This will make it more similar to the wavefront web page. The value is for the status field in alert data. Return its         tty colored string accordingly The value is for the severity a field in alert data. Return its         tty colored string accordingly Depending on the key and the color setting from the command line         we may want to color the output. This function returns the colored version         of v if desired or if possible # We only color-code alert states and severity information. Nothing else. # This is similar to the wavefront webpage interface. Format the given value for a nice print in the summary table Given a wavefrontClient object return the function to call to get all         alerts from the wavefront Api server Given a wavefrontClient object return the function to call to get all         deleted alerts from the wavefront Api server Given a wavefrontClient object return the function to call to update         one alert in wavefront api server Given a wavefrontClient object return the function to call to create         one new alert in wavefront api server Return the extension used for the file on disc representing this         resource # Save a reference of self to the static global list. Create a Dashboard object from the given dict dictionary Return a unique id representing this Alert.         It is the id field assigned by the wavefront api server # Return the one line summary string. This string becomes the row in the # summary table representing this alert.