#!/usr/bin/env python
"""Instant output plugins used by the API for on-the-fly conversion."""



import itertools
import re

from grr.lib import export
from grr.lib import rdfvalue
from grr.lib import registry
from grr.lib import utils


class InstantOutputPlugin(object):
  """The base class for instant output plugins.

  Instant output plugins do on-the-fly data conversion and are used in
  GetExportedFlowResults/GetExportedHuntResults methods.
  """

  __metaclass__ = registry.MetaclassRegistry
  __abstract = True  # pylint: disable=g-bad-name

  plugin_name = None
  friendly_name = None
  description = None
  output_file_extension = ""

  @classmethod
  def GetPluginClassByPluginName(cls, name):
    for plugin_cls in cls.classes.values():
      if plugin_cls.plugin_name == name:
        return plugin_cls

    raise KeyError("No plugin with name attribute '%s'." % name)

  def __init__(self, source_urn=None, token=None):
    """OutputPlugin constructor.

    Args:
      source_urn: URN identifying source of the data (hunt or flow).
      token: Security token.

    Raises:
      ValueError: If one of the keyword arguments is empty.
    """
    super(InstantOutputPlugin, self).__init__()

    if not source_urn:
      raise ValueError("source_urn can't be empty.")

    if not token:
      raise ValueError("token can't be empty.")

    self.source_urn = source_urn
    self.token = token

  @property
  def output_file_name(self):
    """Name of the file where plugin's output should be written to."""

    safe_path = re.sub(r":|/", "_", self.source_urn.Path().lstrip("/"))
    return "results_%s%s" % (safe_path, self.output_file_extension)

  def Start(self):
    """Start method is called in the beginning of the export.

    Yields:
      Chunks of bytes.
    """

  def ProcessValues(self, value_cls, values_generator_fn):
    """Processes a batch of values with the same type.

    ProcessValues is called *once per value type* for each value type in
    the flow/hunt results collection.

    Args:
      value_cls: Class identifying type of the values to be processed.
      values_generator_fn: Function returning an iterable with values. Each
          value is a GRRMessage wrapping a value of a value_cls type.
          values_generator_fn may be called multiple times within
          1 ProcessValues() call - for example, when multiple passes over
          the data are required.