"""This file contains the storage factory class."""

from plaso.lib import definitions

from plaso.storage.sqlite import reader as sqlite_reader
from plaso.storage.sqlite import sqlite_file
from plaso.storage.sqlite import writer as sqlite_writer

try:
  from plaso.storage.redis import reader as redis_reader
  from plaso.storage.redis import writer as redis_writer
except ModuleNotFoundError:
  redis_reader = None
  redis_writer = None


class StorageFactory:
  """Storage factory."""

  @classmethod
  def CreateStorageFile(cls, storage_format):
    """Creates a storage file.

    Args:
      storage_format (str): storage format.

    Returns:
      StorageFile: a storage file or None if the storage file cannot be
          opened or the storage format is not supported.
    """
    if storage_format == definitions.STORAGE_FORMAT_SQLITE:
      return sqlite_file.SQLiteStorageFile()

    return None

  @classmethod
  def CreateStorageReaderForFile(cls, path):
    """Creates a storage reader based on the file.

    Args:
      path (str): path to the storage file.

    Returns:
      StorageReader: a storage reader or None if the storage file cannot be
          opened or the storage format is not supported.
    """
    if sqlite_file.SQLiteStorageFile.CheckSupportedFormat(path):
      return sqlite_reader.SQLiteStorageReader(path)

    return None

  @classmethod
  def CreateStorageWriter(cls, storage_format):
    """Creates a storage writer.

    Args:
      storage_format (str): storage format.

    Returns:
      StorageWriter: a storage writer or None if the storage file cannot be
          opened or the storage format is not supported.
    """
    if storage_format == definitions.STORAGE_FORMAT_SQLITE:
      return sqlite_writer.SQLiteStorageWriter()

    if storage_format == definitions.STORAGE_FORMAT_REDIS and redis_writer:
      return redis_writer.RedisStorageWriter()

    return None

  @classmethod
  def CreateStorageWriterForFile(cls, path):
    """Creates a storage writer based on the file.

    Args:
      path (str): path to the storage file.

    Returns:
      StorageWriter: a storage writer or None if the storage file cannot be
          opened or the storage format is not supported.
    """
    if sqlite_file.SQLiteStorageFile.CheckSupportedFormat(path):
      return sqlite_writer.SQLiteStorageWriter()

    return None

  @classmethod
  def CreateTaskStorageReader(cls, storage_format, task, path):
    """Creates a task storage reader.

    Args:
      storage_format (str): storage format.
      task (Task): task the storage changes are part of.
      path (str): path to the storage file.

    Returns:
      StorageReader: a storage reader or None if the storage file cannot be
          opened or the storage format is not supported.
    """
    if storage_format == definitions.STORAGE_FORMAT_SQLITE:
      return sqlite_reader.SQLiteStorageReader(path)

    if storage_format == definitions.STORAGE_FORMAT_REDIS and redis_reader:
      return redis_reader.RedisStorageReader(
          task.session_identifier, task.identifier)

    return None

  @classmethod
  def CreateTaskStorageWriter(cls, storage_format):
    """Creates a task storage writer.

    Args:
      storage_format (str): storage format.

    Returns:
      StorageWriter: a storage writer or None if the storage file cannot be
          opened or the storage format is not supported.
    """
    if storage_format == definitions.STORAGE_FORMAT_SQLITE:
      return sqlite_writer.SQLiteStorageWriter(
          storage_type=definitions.STORAGE_TYPE_TASK)

    if storage_format == definitions.STORAGE_FORMAT_REDIS and redis_writer:
      return redis_writer.RedisStorageWriter(
          storage_type=definitions.STORAGE_TYPE_TASK)

    return None
