# Copyright (C) 2020  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information

from types import TracebackType
from typing import Any, Dict, Optional, Type


class Exporter:
    """
    Base class for all the exporters.

    Each export can have multiple exporters, so we can read the journal a single
    time, then export the objects we read in different formats without having to
    re-read them every time.

    Override this class with the behavior for an export in a specific export
    format. You have to overwrite process_object() to make it write to the
    appropriate export files.

    You can also put setup and teardown logic in __enter__ and __exit__, and it
    will be called automatically.
    """

    def __init__(self, config: Dict[str, Any], *args: Any, **kwargs: Any) -> None:
        self.config: Dict[str, Any] = config

    def __enter__(self) -> "Exporter":
        return self

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_value: Optional[BaseException],
        traceback: Optional[TracebackType],
    ) -> Optional[bool]:
        pass

    def process_object(self, object_type: str, obj: Dict[str, Any]) -> None:
        """
        Process a SWH object to export.

        Override this with your custom exporter.
        """
        raise NotImplementedError


class ExporterDispatch(Exporter):
    """
    Like Exporter, but dispatches each object type to a different function
    (e.g you can override `process_origin(self, object)` to process origins.)
    """

    def process_object(self, object_type: str, obj: Dict[str, Any]) -> None:
        method_name = "process_" + object_type
        if hasattr(self, method_name):
            getattr(self, method_name)(obj)
