"""JSON-L parser plugin for Docker layer configuration files."""

from plaso.containers import events
from plaso.parsers import jsonl_parser
from plaso.parsers.jsonl_plugins import interface


class DockerLayerConfigurationEventData(events.EventData):
    """Docker layer configuration event data.

    Attributes:
      command: the command used which made Docker create a new layer.
      creation_time (dfdatetime.DateTimeValues): date and time the layer
          was created (added).
      layer_identifier: the identifier of the current Docker layer (SHA-1).
    """

    DATA_TYPE = "docker:layer:configuration"

    def __init__(self):
        """Initializes event data."""
        super().__init__(data_type=self.DATA_TYPE)
        self.command = None
        self.creation_time = None
        self.layer_identifier = None


class DockerLayerConfigurationJSONLPlugin(interface.JSONLPlugin):
    """JSON-L parser plugin for Docker layer configuration files.

    This parser handles per Docker layer configuration files stored in:
    DOCKER_DIR/graph/<layer_identifier>/json
    """

    NAME = "docker_layer_config"
    DATA_FORMAT = "Docker layer configuration file"

    def _GetLayerIdentifierFromPath(self, parser_mediator):
        """Extracts a layer (or graph) identifier from a path.

        Args:
          parser_mediator (ParserMediator): mediates interactions between parsers and
              other components, such as storage and dfVFS.

        Returns:
          str: layer identifier.
        """
        file_entry = parser_mediator.GetFileEntry()
        file_system = file_entry.GetFileSystem()

        path_segments = file_system.SplitPath(file_entry.path_spec.location)
        # TODO: validate format of layer identifier.
        return path_segments[-2]

    def _ParseRecord(self, parser_mediator, json_dict):
        """Parses a Docker layer configuration record.

        Args:
          parser_mediator (ParserMediator): mediates interactions between parsers and
              other components, such as storage and dfVFS.
          json_dict (dict): JSON dictionary of the configuration record.
        """
        command = None
        container_configuration = self._GetJSONValue(json_dict, "container_config")
        if container_configuration:
            command_arguments = self._GetJSONValue(container_configuration, "Cmd")
            if command_arguments:
                command = " ".join(
                    [
                        command_argument.replace("\t", "").strip()
                        for command_argument in command_arguments
                    ]
                )

        date_time, corrupted = self._ParseISO8601DateTimeString(
            parser_mediator, json_dict, "created"
        )
        event_data = DockerLayerConfigurationEventData()
        event_data.command = command
        event_data.creation_time = date_time
        event_data.layer_identifier = self._GetLayerIdentifierFromPath(parser_mediator)

        parser_mediator.ProduceEventData(event_data, corrupted=corrupted)

    def CheckRequiredFormat(self, json_dict):
        """Check if the record has the minimal structure required by the plugin.

        Args:
          json_dict (dict): JSON dictionary of the configuration record.

        Returns:
          bool: True if this is the correct parser, False otherwise.
        """
        container_configuration = json_dict.get("container_config") or None
        docker_version = json_dict.get("docker_version") or None

        if None in (container_configuration, docker_version):
            return False

        return True


jsonl_parser.JSONLParser.RegisterPlugin(DockerLayerConfigurationJSONLPlugin)
