"""The Mimeo File Consumer module.

It exports only one class:
    * FileConsumer
        A Consumer implementation saving data in the filesystem.
"""
from __future__ import annotations

import logging
from pathlib import Path
from typing import Collection, Generator

import aiofiles

from mimeo.config.mimeo_config import MimeoOutput
from mimeo.consumers import Consumer

logger = logging.getLogger(__name__)


class FileConsumer(Consumer):
    """A Consumer implementation saving data in the filesystem.

    This Consumer is instantiated for the 'file' output direction
    and saves data produced by Mimeo as files using Mimeo Output Details.

    Methods
    -------
    consume
        Save data generated by Mimeo into a file.

    Attributes
    ----------
    directory : str
        A directory path to save files within
    output_path_tmplt : str
        An output file path template
        (every file has its index inside the actual path)
    """

    def __init__(
            self,
            output: MimeoOutput,
    ):
        """Initialize FileConsumer class.

        Parameters
        ----------
        output : MimeoOutput
            Configured Mimeo Output Details
        """
        self.directory: str = output.directory_path
        self.output_path_tmplt: str = f"{self.directory}/{output.file_name}"

    async def consume(
            self,
            data: Collection | Generator,
    ) -> None:
        """Save data generated by Mimeo into a file.

        It is an implementation of Consumer's abstract method.
        If the output directory does not exist it is created.
        Every file name has an index inside its path.

        Parameters
        ----------
        data : Collection | Generator
            Stringified data generated by Mimeo
        """
        count = 0
        for data_unit in data:
            logger.fine("Consuming data [%s]", data_unit)
            if not Path(self.directory).exists():
                logger.info("Creating output directory [%s]", self.directory)
                Path(self.directory).mkdir(parents=True, exist_ok=True)

            count += 1
            file_name = self.output_path_tmplt.format(count)

            logger.info("Writing data into file [%s]", file_name)
            async with aiofiles.open(file_name, mode="w") as file:
                await file.write(data_unit)
