"""Processing configuration classes."""

from acstore.containers import interface


class CredentialConfiguration(interface.AttributeContainer):
    """Configuration settings for a credential.

    Attributes:
      credential_data (bytes): credential data.
      credential_type (str): credential type.
      path_spec (dfvfs.PathSpec): path specification.
    """

    CONTAINER_TYPE = "credential_configuration"

    def __init__(self, credential_data=None, credential_type=None, path_spec=None):
        """Initializes a credential configuration object.

        Args:
          credential_data (Optional[bytes]): credential data.
          credential_type (Optional[str]): credential type.
          path_spec (Optional[dfvfs.PathSpec]): path specification.
        """
        super().__init__()
        self.credential_data = credential_data
        self.credential_type = credential_type
        self.path_spec = path_spec


class EventExtractionConfiguration(interface.AttributeContainer):
    """Configuration settings for event extraction.

    These settings are primarily used by the parser mediator.

    Attributes:
      filter_object (objectfilter.Filter): filter that specifies which
          events to include.
    """

    CONTAINER_TYPE = "event_extraction_configuration"

    def __init__(self):
        """Initializes an event extraction configuration object."""
        super().__init__()
        self.filter_object = None


class ExtractionConfiguration(interface.AttributeContainer):
    """Configuration settings for extraction.

    These settings are primarily used by the extraction worker.

    Attributes:
      archive_types_string (str): comma separated archive types for which embedded
          file entries should be processed.
      extract_winevt_resources (bool): True if Windows EventLog resources should
          be extracted.
      extract_winreg_binary (bool): True if Windows Registry binary values should
          be extracted.
      hasher_file_size_limit (int): maximum file size that hashers
          should process, where 0 or None represents unlimited.
      hasher_names_string (str): comma separated names of hashers to use during
          processing.
      process_compressed_streams (bool): True if file content in compressed
          streams should be processed.
      yara_rules_string (str): Yara rule definitions.
    """

    CONTAINER_TYPE = "extraction_configuration"

    def __init__(self):
        """Initializes an extraction configuration object."""
        super().__init__()
        self.archive_types_string = None
        self.extract_winevt_resources = True
        self.extract_winreg_binary = False
        self.hasher_file_size_limit = None
        self.hasher_names_string = None
        self.process_compressed_streams = True
        self.yara_rules_string = None


class ProfilingConfiguration(interface.AttributeContainer):
    """Configuration settings for profiling.

    Attributes:
      directory (str): path to the directory where the profiling sample files
          should be stored.
      profilers (set(str)): names of the profilers to enable.
          Supported profilers are:

          * 'format_checks', which profiles CPU time consumed per format check;
          * 'memory', which profiles memory usage;
          * 'parsers', which profiles CPU time consumed by individual parsers;
          * 'processing', which profiles CPU time consumed by different parts of
            processing;
          * 'serializers', which profiles CPU time consumed by individual
            serializers.
          * 'storage', which profiles storage reads and writes.
      sample_rate (int): the profiling sample rate. Contains the number of event
          sources processed.
    """

    CONTAINER_TYPE = "profiling_configuration"

    def __init__(self):
        """Initializes a profiling configuration object."""
        super().__init__()
        self.directory = None
        self.profilers = set()
        self.sample_rate = 1000

    def HaveProfileAnalyzers(self):
        """Determines if analyzers profiling is configured.

        Returns:
          bool: True if analyzers profiling is configured.
        """
        return "analyzers" in self.profilers

    def HaveProfileFormatChecks(self):
        """Determines if format checks profiling is configured.

        Returns:
          bool: True if format checks profiling is configured.
        """
        return "format_checks" in self.profilers

    def HaveProfileMemory(self):
        """Determines if memory profiling is configured.

        Returns:
          bool: True if memory profiling is configured.
        """
        return "memory" in self.profilers

    def HaveProfileParsers(self):
        """Determines if parsers profiling is configured.

        Returns:
          bool: True if parsers profiling is configured.
        """
        return "parsers" in self.profilers

    def HaveProfileProcessing(self):
        """Determines if processing profiling is configured.

        Returns:
          bool: True if processing profiling is configured.
        """
        return "processing" in self.profilers

    def HaveProfileSerializers(self):
        """Determines if serializers profiling is configured.

        Returns:
          bool: True if serializers profiling is configured.
        """
        return "serializers" in self.profilers

    def HaveProfileStorage(self):
        """Determines if storage profiling is configured.

        Returns:
          bool: True if storage profiling is configured.
        """
        return "storage" in self.profilers

    def HaveProfileTaskQueue(self):
        """Determines if task queue profiling is configured.

        Returns:
          bool: True if task queue profiling is configured.
        """
        return "task_queue" in self.profilers

    def HaveProfileTasks(self):
        """Determines if tasks profiling is configured.

        Returns:
          bool: True if task queue profiling is configured.
        """
        return "tasks" in self.profilers


class ProcessingConfiguration(interface.AttributeContainer):
    """Configuration settings for processing.

    Attributes:
      artifact_definitions_path (str): path to artifact definitions directory or file.
      artifact_filters (Optional list[str]): names of artifact definitions that are used
          for filtering file system and Windows Registry key paths.
      credentials (list[CredentialConfiguration]): credential configurations.
      custom_artifacts_path (str): path to custom artifact definitions directory or
          file.
      custom_formatters_path (str): path to custom formatter definitions file.
      data_location (str): path to the data files.
      debug_output (bool): True if debug output should be enabled.
      dynamic_time (bool): True if date and time values should be represented in their
          granularity or semantically.
      event_extraction (EventExtractionConfiguration): event extraction configuration.
      extraction (ExtractionConfiguration): extraction configuration.
      filter_file (str): path to a file with find specifications.
      force_parser (bool): True if a specified parser should be forced to be used to
          extract events.
      log_filename (str): name of the log file.
      parser_filter_expression (str): parser filter expression, where None represents
          all parsers and plugins.
      preferred_codepage (str): preferred codepage.
      preferred_encoding (str): preferred output encoding.
      preferred_language (str): preferred language.
      preferred_time_zone (str): preferred time zone.
      preferred_year (int): preferred initial year value for year-less date and time
          values.
      profiling (ProfilingConfiguration): profiling configuration.
      task_storage_format (str): format to use for storing task results.
      task_storage_path (str): path of the directory containing SQLite task storage
          files.
      temporary_directory (str): path of the directory for temporary files.
      use_fallback_hostname (bool): use the hostname value derived pre-processing as
          fallback for the hostname output field.
      use_fallback_path (bool): use the event data stream path specification value as
          fallback for the filename and inode output fields.
    """

    CONTAINER_TYPE = "processing_configuration"

    def __init__(self):
        """Initializes a process configuration object."""
        super().__init__()
        self.artifact_definitions_path = None
        self.artifact_filters = None
        self.credentials = []
        self.custom_artifacts_path = None
        self.custom_formatters_path = None
        self.data_location = None
        self.debug_output = False
        self.dynamic_time = False
        self.event_extraction = EventExtractionConfiguration()
        self.extraction = ExtractionConfiguration()
        self.filter_file = None
        self.force_parser = None
        self.log_filename = None
        self.parser_filter_expression = None
        self.preferred_codepage = None
        self.preferred_encoding = None
        self.preferred_language = None
        self.preferred_time_zone = None
        self.preferred_year = None
        self.profiling = ProfilingConfiguration()
        self.task_storage_format = None
        self.task_storage_path = None
        self.temporary_directory = None
        self.use_fallback_hostname = None
        self.use_fallback_path = None
