"""This file contains the interface for analysis plugins."""

import abc
import calendar
import collections
import time

from plaso.analysis import definitions as analysis_definitions
from plaso.analysis import logger
from plaso.containers import events
from plaso.containers import reports
from plaso.lib import definitions


class AnalysisPlugin:
    """Class that defines the analysis plugin interface."""

    # The name of the plugin. This is the name that is matched against when
    # loading plugins, so it is important that this name is short, concise and
    # explains the nature of the plugin easily. It also needs to be unique.
    NAME = "analysis_plugin"

    # Flag to indicate the analysis is for testing purposes only.
    TEST_PLUGIN = False

    def __init__(self):
        """Initializes an analysis plugin."""
        super().__init__()
        self._analysis_counter = collections.Counter()
        self.plugin_type = analysis_definitions.PLUGIN_TYPE_REPORT

    @property
    def plugin_name(self):
        """str: name of the plugin."""
        return self.NAME

    def _CreateEventTag(self, event, labels):
        """Creates an event tag.

        Args:
          event (EventObject): event to tag.
          labels (list[str]): event tag labels.

        Returns:
          EventTag: the event tag.
        """
        event_identifier = event.GetIdentifier()

        event_tag = events.EventTag()
        event_tag.SetEventIdentifier(event_identifier)
        event_tag.AddLabels(labels)

        event_identifier_string = event_identifier.CopyToString()
        labels_string = ", ".join(labels)
        logger.debug(
            f"Tagged event: {event_identifier_string:s} with labels: "
            f"{labels_string:s}"
        )
        return event_tag

    # pylint: disable=unused-argument
    def CompileReport(self, analysis_mediator):
        """Compiles a report of the analysis.

        After the plugin has received every copy of an event to analyze this
        function will be called so that the report can be assembled.

        Args:
          analysis_mediator (AnalysisMediator): mediates interactions between
              analysis plugins and other components, such as storage and dfVFS.

        Returns:
          AnalysisReport: report.
        """
        analysis_report = reports.AnalysisReport(plugin_name=self.NAME)

        time_elements = time.gmtime()
        time_compiled = calendar.timegm(time_elements)
        analysis_report.time_compiled = (
            time_compiled * definitions.MICROSECONDS_PER_SECOND
        )
        analysis_report.analysis_counter = self._analysis_counter

        return analysis_report

    @abc.abstractmethod
    def ExamineEvent(self, analysis_mediator, event, event_data, event_data_stream):
        """Analyzes an event.

        Args:
          analysis_mediator (AnalysisMediator): mediates interactions between
              analysis plugins and other components, such as storage and dfVFS.
          event (EventObject): event.
          event_data (EventData): event data.
          event_data_stream (EventDataStream): event data stream.
        """
