import os
from dataclasses import dataclass
from pathlib import Path

from mlf_core.common.version import load_mlf_core_template_version
from mlf_core.create.domains.mlf_core_template_struct import MlfcoreTemplateStruct
from mlf_core.create.github_support import prompt_github_repo
from mlf_core.create.template_creator import TemplateCreator
from mlf_core.custom_cli.questionary import mlf_core_questionary_or_dot_mlf_core


@dataclass
class TemplateStructPackage(MlfcoreTemplateStruct):
    """
    PACKAGE-PREDICTION
    """

    framework: str = ""  # which machine learning framework to use


class PackageCreator(TemplateCreator):
    def __init__(self):
        self.package_struct = TemplateStructPackage(domain="package")
        super().__init__(self.package_struct)
        self.WD_Path = Path(os.path.dirname(__file__))
        self.TEMPLATES_PACKAGE_PATH = f"{self.WD_Path.parent}/templates/package"

        '"" TEMPLATE VERSIONS ""'
        self.PACKAGE_PREDICTION_TEMPLATE_VERSION = load_mlf_core_template_version(
            "package-prediction", self.AVAILABLE_TEMPLATES_PATH
        )

    def create_template(self, path: Path, dot_mlf_core):
        """
        Handles the package domain. Prompts the user for the language, general and domain specific options.
        """

        self.package_struct.language = mlf_core_questionary_or_dot_mlf_core(
            function="select",
            question="Choose the project's primary purpose",
            choices=["prediction"],
            default="prediction",
            dot_mlf_core=dot_mlf_core,
            to_get_property="language",
        )

        # prompt the user to fetch general template configurations
        super().prompt_general_template_configuration(dot_mlf_core)

        # switch case statement to prompt the user to fetch template specific configurations
        switcher = {
            "prediction": self.package_prediction_options,
        }
        switcher.get(self.package_struct.language)(dot_mlf_core)  # type: ignore

        (
            self.package_struct.is_github_repo,
            self.package_struct.is_repo_private,
            self.package_struct.is_github_orga,
            self.package_struct.github_orga,
        ) = prompt_github_repo(dot_mlf_core)

        if self.package_struct.is_github_orga:
            self.package_struct.github_username = self.package_struct.github_orga
        # create the chosen and configured template
        super().create_template_without_subdomain(self.TEMPLATES_PACKAGE_PATH)

        # switch case statement to fetch the template version
        switcher_version = {
            "package": self.PACKAGE_PREDICTION_TEMPLATE_VERSION,
        }
        self.package_struct.template_version, self.package_struct.template_handle = (
            switcher_version.get(self.package_struct.language),  # type: ignore
            f"package-{self.package_struct.language.lower()}",  # type: ignore
        )

        # perform general operations like creating a GitHub repository and general linting
        super().process_common_operations(
            path=Path(path).resolve(),
            domain="package",
            language=self.package_struct.language,  # type: ignore
            dot_mlf_core=dot_mlf_core,
        )

    def package_prediction_options(self, dot_mlf_core):
        """ Prompts for package-prediction specific options and saves them into the PackageTemplateStruct """
        self.package_struct.framework = mlf_core_questionary_or_dot_mlf_core(
            function="select",
            question="Choose a framework",
            choices=["pytorch", "tensorflow", "xgboost"],
            default="pytorch",
            dot_mlf_core=dot_mlf_core,
            to_get_property="framework",
        )
