import os
from dataclasses import dataclass

from actions_logging.app_logging import logger
from aws.constants import PROD_ENVS, PRODUCTION, STAGING, STG_PROD_ENVS
from aws.env_info import get_env_region
from frontend.constants import SERVICES_WITH_CHECKPOINT_BUNDLE
from git.utils import get_commit_hash
from github.env import bool_to_gh_str, exit_on_error_and_write_summary, get_required_env_var, write_github_output
from master.calculate_version import get_version


@dataclass
class FEBuildConfig:
    """
    A class to configure and export environment variables for frontend builds and deployments.

    Attributes:
        build (str): Indicates if a build is being performed.
        env_name (str): The name of the environment (e.g., staging, production).
        svc_name (str): The name of the service being built or deployed.
        checkpoint (str): A checkpoint identifier for the build process.
        version_to_deploy (str): The version of the application to deploy.
        new_version (str): The new version of the application being built.
        github_run_number (str): The GitHub Actions run number.
        env_file_version (str): The version of the environment file provided as input.

    Methods:
        export_env_vars():
            Exports environment variables based on the build and deployment configuration.
            Validates production builds and deploys, determines the final version and environment
            file version, and writes the necessary variables to the GitHub environment.
    """

    build: str
    env_name: str
    svc_name: str
    checkpoint: str
    version_to_deploy: str
    new_version: str
    github_run_number: str
    env_file_version: str

    def export_env_vars(self):
        if self.env_name in PROD_ENVS and self.build:
            exit_on_error_and_write_summary(
                (
                    "Manual direct production builds are not allowed",
                    "Please build for staging environment and use that version",
                    "as version parameter to deploy to production",
                )
            )

        if self.env_name in PROD_ENVS and self.version_to_deploy:
            version_is_prod_hotfix = False
            version_split = self.version_to_deploy.split("-")
            if len(version_split) == 3 and version_split[0] == STAGING:
                version_is_prod_hotfix = True
            if not (version_is_prod_hotfix or get_version(self.version_to_deploy)):
                exit_on_error_and_write_summary(
                    "Production frontend deploy can only be done with semver or "
                    "production hotfix (staging-BUILD_ID-RUN_ID) versions. "
                    f"{self.version_to_deploy} supplied."
                )

        final_env_vars_version = self.env_file_version
        if not final_env_vars_version:
            final_env_vars_version = ""

        is_hotfix = False
        if (self.env_name == STAGING or PRODUCTION in self.env_name) and self.build:
            logger.info_green("This is a hotfix build & deploy")
            is_hotfix = True

        deploy_checkpoint_artifact = False
        if self.svc_name in SERVICES_WITH_CHECKPOINT_BUNDLE and (self.checkpoint or self.env_name in STG_PROD_ENVS):
            deploy_checkpoint_artifact = True

        build_checkpoint_artifact = False
        if self.build and deploy_checkpoint_artifact:
            build_checkpoint_artifact = True

        final_version = self.version_to_deploy[1:] if self.version_to_deploy.startswith("v") else self.version_to_deploy
        logger.info_yellow(f"package version to deploy: {final_version}")
        if not final_version:
            logger.info_yellow("configuring version for new build since VERSION_TO_DEPLOY was not provided")
            git_hash = get_commit_hash()
            version_suffix = f"{self.github_run_number}-{git_hash}"
            new_version = f"{self.env_name}-{version_suffix}"
            logger.info_yellow(f"new artifact version is being build: {new_version}")
            final_version = new_version
            write_github_output(version_suffix, "VERSION_SUFFIX")

        build_generic_fe_package = False
        if is_hotfix or (self.build and not self.checkpoint):
            build_generic_fe_package = True

        deploy_generic_fe_package = False
        if self.env_name in STG_PROD_ENVS or not self.checkpoint:
            deploy_generic_fe_package = True

        deploy_cp_us_standalone = False
        region = get_env_region(self.env_name)
        if region == "us-east-1" and deploy_generic_fe_package:
            logger.info_yellow(f"{self.env_name} is in {region}, will deploy cp standalone application")
            deploy_cp_us_standalone = True

        write_github_output(bool_to_gh_str(deploy_cp_us_standalone), "DEPLOY_CP_US_STANDALONE")
        write_github_output(bool_to_gh_str(build_generic_fe_package), "BUILD_GENERIC_FE_PACKAGE")
        write_github_output(bool_to_gh_str(deploy_generic_fe_package), "DEPLOY_GENERIC_FE_PACKAGE")
        write_github_output(bool_to_gh_str(build_checkpoint_artifact), "BUILD_CHECKPOINT_ARTIFACT")
        write_github_output(bool_to_gh_str(deploy_checkpoint_artifact), "DEPLOY_CHECKPOINT_ARTIFACT")
        write_github_output(final_env_vars_version, "FINAL_ENV_VARS_VERSION")
        write_github_output(final_version, "FINAL_VERSION")
        write_github_output(bool_to_gh_str(is_hotfix), "IS_HOTFIX")


if __name__ == "__main__":
    fe_build_conf = FEBuildConfig(
        **{
            "build": os.getenv("BUILD_ARTIFACT", "false") == "true",
            "env_name": get_required_env_var("ENV_NAME"),
            "svc_name": get_required_env_var("SVC_NAME"),
            "checkpoint": os.getenv("CHECKPOINT", "false") == "true",
            "version_to_deploy": os.getenv("VERSION_TO_DEPLOY"),
            "new_version": os.getenv("NEW_VERSION"),
            "github_run_number": os.getenv("GITHUB_RUN_NUMBER"),
            "env_file_version": os.getenv("ENV_FILE_VERSION"),
        }
    )
    fe_build_conf.export_env_vars()
