from pathlib import Path
from typing import cast
from logic.settings import Settings, SettingsDTO
from logic.queue import Queue, CompressibleDto, FileGroupDto, SingleFileDto
from modules.converter import TextureConverter
from modules.compressor import TextureCompressor
from modules.optimizer import TextureOptimizer


class App:
    """The application itself.

    :var config: Configuration of this application.
    :type config: SettingsDTO
    :var queue: Queue of file groups to process.
    :type queue: list[CompressibleDto]
    :var converter: Custom tool that handles interaction with batch files stored in the folder of each .heo file.
    :type converter: TextureConverter
    :var compressor: Custom tool that handles interaction with external script called HEOTexComp.
    :type compressor: TextureCompressor
    :var optimizer: Custom tool that handles interaction with external script called HEOSameTexOptimizer.
    :type optimizer: TextureOptimizer
    """

    def __init__(self, config_file: Path, queue_file: Path):
        """Class constructor.

        :param config_file: Absolute path to the file where settings stored as JSON object.
        :type config_file: Path
        :param queue_file: Absolute path to the file where queue of .heo files stored as JSON object.
        :type queue_file: Path
        """

        # Import settings from the provided file.
        self.config = Settings(config_file.absolute()).get()

        # Import the queue (of .heo targets to be processed) from the provided file.
        self.queue = Queue(queue_file.absolute()).get()

        # Initialize custom "TextureConverter" tool for processing auto-generated .bat files inside the folder of each
        # target .heo file.
        self.converter = TextureConverter(self.config.batch_types)

        # Initialize external tool initially called "HEOTexComp" through the custom "TextureCompressor" tool.
        self.compressor = TextureCompressor()

        # Initialize external tool initially called "HEOSameTexOptimizer" through the custom "TextureOptimizer" tool.
        self.optimizer = TextureOptimizer(Path("./cache~"))

    def run(self):
        """Executing manipulations with .heo objects based on provided files."""

        # Reading all compressible targets in the queue one by one.
        for target in self.queue:

            # Checking is this compressible target a group of .heo files
            if target.is_group:

                # Explicit type cast to get proper access to all fields of the inherited subclass
                file_group = cast(FileGroupDto, target)

                # Reading full paths to all .heo files in the current group.
                for target_file in file_group.files:
                    # Executing all existing .bat scripts for the current .heo file.
                    self.converter.process_file(target_file)

                    # Executing HEOTexComp for the current .heo file.
                    self.compressor.process_file(target_file)

                # Running HEOSameTexOptimizer for this group of .heo files, saving the result in a new folder named
                # by the specified group name.
                self.optimizer.process_files(file_group.files, file_group.export_path, file_group.group_name)

            # Otherwise it is a single .heo file that doesn't need to be processed with HEOSameTexOptimizer tool
            else:

                # Explicit type cast to get proper access to all fields of the inherited subclass
                single_file = cast(SingleFileDto, target)

                # Executing all existing .bat scripts for the current .heo file.
                self.converter.process_file(single_file.file)

                # Executing HEOTexComp for the current .heo file.
                self.compressor.process_file(single_file.file)
