"""Mloq setup command implementation."""
from pathlib import Path
from typing import List, Tuple

import click
from omegaconf import DictConfig

from mloq.command import Command, CommandMixin
from mloq.record import CMDRecord


def _sub_commands():
    from mloq.commands import (
        CiCMD,
        DockerCMD,
        DocsCMD,
        GlobalsCMD,
        LicenseCMD,
        LintCMD,
        PackageCMD,
        ProjectCMD,
        RequirementsCMD,
    )

    return (
        GlobalsCMD,
        ProjectCMD,
        PackageCMD,
        LicenseCMD,
        LintCMD,
        CiCMD,
        DocsCMD,
        DockerCMD,
        RequirementsCMD,
    )


SUB_COMMANDS = _sub_commands()


class SetupCMD(CommandMixin):
    """Implement the functionality of the setup Command."""

    cmd_name = "setup"
    files = tuple([file for cmd in SUB_COMMANDS for file in cmd.files])
    SUB_COMMAND_CLASSES = SUB_COMMANDS

    def __init__(self, record: CMDRecord, interactive: bool = False):
        """
        Initialize a SetupCMD class.

        Args:
            record: CMDRecord where the command data will be written.
            interactive: If True, parse the command configuration in interactive mode.
        """
        super(SetupCMD, self).__init__(record=record, interactive=interactive)
        self._sub_commands = [
            cmd(record=self.record, interactive=interactive) for cmd in self.SUB_COMMAND_CLASSES
        ]
        self.files = tuple([file for cmd in self._sub_commands for file in cmd.files])

    @property
    def config(self) -> DictConfig:
        """List of all the commands that will be executed when running mloq setup."""
        return self.record.config

    @property
    def sub_commands(self) -> List[Command]:
        """List of all the commands that will be executed when running mloq setup."""
        return self._sub_commands

    @property
    def directories(self) -> Tuple[Path]:
        """Tuple containing Paths objects representing the directories created by the command."""
        return tuple([directory for cmd in self.sub_commands for directory in cmd.directories])

    def interactive_config(self) -> DictConfig:
        """Generate the configuration of the project interactively."""
        click.echo("Provide the values to generate the project configuration.")
        for cmd in self.sub_commands:
            cmd.interactive_config()
        return self.record.config

    def parse_config(self) -> DictConfig:
        """Update the configuration DictConfig with the Command parameters."""
        for cmd in self.sub_commands:
            cmd.parse_config()
        return self.record.config

    def run_side_effects(self) -> None:
        """Apply additional configuration methods."""
        for cmd in self.sub_commands:
            cmd.run_side_effects()

    def record_files(self) -> None:
        """Register the files that will be generated by mloq."""
        for cmd in self.sub_commands:
            cmd.record_files()
