"""The hashing analyzer implementation."""

from plaso.analyzers import interface
from plaso.analyzers import logger
from plaso.analyzers import manager
from plaso.analyzers.hashers import manager as hashers_manager
from plaso.containers import analyzer_result
from plaso.lib import definitions


class HashingAnalyzer(interface.BaseAnalyzer):
  """This class contains code for calculating file hashes of input files.

  In Plaso, hashers are classes that map arbitrarily sized file content to a
  fixed size value. See:
  https://en.wikipedia.org/wiki/Hash_function
  """

  NAME = 'hashing'
  DESCRIPTION = 'Calculates hashes of file content.'

  PROCESSING_STATUS_HINT = definitions.STATUS_INDICATOR_HASHING

  INCREMENTAL_ANALYZER = True

  def __init__(self):
    """Initializes a hashing analyzer."""
    super().__init__()
    self._hasher_names_string = ''
    self._hashers = []

  def Analyze(self, data):
    """Updates the internal state of the analyzer, processing a block of data.

    Repeated calls are equivalent to a single call with the concatenation of
    all the arguments.

    Args:
      data (bytes): block of data from the data stream.
    """
    for hasher in self._hashers:
      hasher.Update(data)

  def GetResults(self):
    """Retrieves the hashing results.

    Returns:
      list[AnalyzerResult]: results.
    """
    results = []
    for hasher in self._hashers:
      logger.debug(f'Processing results for hasher {hasher.NAME:s}')
      result = analyzer_result.AnalyzerResult()
      result.analyzer_name = self.NAME
      result.attribute_name = hasher.ATTRIBUTE_NAME
      result.attribute_value = hasher.GetStringDigest()
      results.append(result)
    return results

  def Reset(self):
    """Resets the internal state of the analyzer."""
    hasher_names = hashers_manager.HashersManager.GetHasherNamesFromString(
        self._hasher_names_string)
    self._hashers = hashers_manager.HashersManager.GetHashers(hasher_names)

  def SetHasherNames(self, hasher_names_string):
    """Sets the hashers that should be enabled.

    Args:
      hasher_names_string (str): comma separated names of hashers to enable.
    """
    hasher_names = hashers_manager.HashersManager.GetHasherNamesFromString(
        hasher_names_string)

    hasher_names_string = ', '.join(hasher_names)
    logger.debug(f'[SetHasherNames] hasher names: {hasher_names_string:s}')

    self._hashers = hashers_manager.HashersManager.GetHashers(hasher_names)
    self._hasher_names_string = hasher_names_string


manager.AnalyzersManager.RegisterAnalyzer(HashingAnalyzer)
