import os
from github.env import exit_on_error_and_write_summary, get_required_env_var, write_github_env, write_github_summary
from actions_logging.app_logging import logger
from common.common import run_command
from aws.ecr import EcrConfig
from git.utils import get_commit_hash
from aws.constants import REPLICATED_IMAGES


def get_dockerfile():
    if os.path.exists("Dockerfile.aws"):
        logger.info_green("Dockerfile.aws found")
        return "Dockerfile.aws"
    elif os.path.exists("Dockerfile"):
        logger.info_green("Dockerfile.aws didn't found. Dockerfile found")
        return "Dockerfile"
    else:
        exit_on_error_and_write_summary("Dockerfile or Dockerfile.aws not found")


def get_container_tag(env_name, build_number, version_to_deploy):
    if version_to_deploy:
        return version_to_deploy
    if not build_number:
        exit_on_error_and_write_summary("build_number not found")
    commit_hash = get_commit_hash()
    return f"{env_name}-{build_number}-{commit_hash}"

def build_docker_args(runtime):
    docker_build_args = os.getenv("DOCKER_BUILD_ARGS")
    if docker_build_args:
        return docker_build_args
    try:
        match runtime:
            case "Java":
                jar_name = get_required_env_var("JAR_NAME")
                build_args = f'--build-arg JAR_NAME="{jar_name}"'
                return build_args
            case "Node":
                node_docker_dist = os.getenv('NODE_DOCKER_DIST', '20.14.0-alpine3.19')
                nodejs_avail_memory = os.getenv('NODEJS_AVAIL_MEMORY', '1536')
                build_args = f'''--build-arg SSH_KEY="$GLOBAL_CICD_P81_PIPELINE_SSH_KEY" \
                --build-arg NODEJS_AVAIL_MEMORY={nodejs_avail_memory} --build-arg NODE_DOCKER_DIST={node_docker_dist}'''
                static_bucket = os.getenv("GLOBAL_CICD_STATIC_BUCKET_SECRET")
                static_bucket_arg = ""
                if static_bucket:
                    static_bucket_arg = f" --build-arg STATIC_BUCKET_SECRET={static_bucket}"
                build_args += static_bucket_arg
                return build_args
            case "Go":
                static_bucket = os.getenv("GLOBAL_CICD_STATIC_BUCKET_SECRET")
                static_bucket_arg = ""
                if static_bucket:
                    static_bucket_arg = f" --build-arg STATIC_BUCKET_SECRET={static_bucket}"
                build_args = static_bucket_arg
                return build_args
            case _:
                raise RuntimeError(f"Detected unsupported language: {runtime}")
    except Exception as e:
        exit_on_error_and_write_summary(f"error in building docker args: {e}")

def docker_build(full_docker_name, build_args):
    try:
        dockerfile_name = get_dockerfile()
        quiet = os.getenv("QUIET", " --quiet")
        no_cache = os.getenv("NO_CACHE", " --no-cache")
        logger.info_green(f"will build docker {full_docker_name}")
        run_command(f"docker build -f {dockerfile_name} -t {full_docker_name}{quiet}{no_cache} {build_args} .")
        logger.info_green(f"docker build {full_docker_name} done")
    except Exception as e:
        exit_on_error_and_write_summary(f"error in docker_build: {e}")

def docker_push(full_docker_name, ecr_config):
    try:
        logger.info_green(f"will push {full_docker_name}")
        run_command(f"aws ecr get-login-password --region {ecr_config.ecr_region} | docker login --username AWS --password-stdin {ecr_config.ecr_url}")
        run_command(f"docker push {full_docker_name}")
        logger.info_green(f"docker push {full_docker_name} done")
    except Exception as e:
        exit_on_error_and_write_summary(f"error in docker_push: {e}")

def docker_copy(full_source_docker_name, replicate_image, ecr_config):
    try:
        logger.info_green(f"will copy from {full_source_docker_name} to {replicate_image}")
        run_command(f"aws ecr get-login-password --region {ecr_config.ecr_region} | docker login --username AWS --password-stdin {ecr_config.ecr_url}")
        run_command(f"docker pull {full_source_docker_name}")
        run_command(f"docker tag {full_source_docker_name} {replicate_image}")
        run_command(f"docker push {replicate_image}")
        logger.info_green(f"docker copy from {full_source_docker_name} to {replicate_image} done")
    except Exception as e:
        exit_on_error_and_write_summary(f"error in docker_copy: {e}")

def main():
    try:
        env_name = get_required_env_var("ENV_NAME")
        svc_name = get_required_env_var("SVC_NAME")
        runtime = get_required_env_var("RUNTIME")
        ecr_config = EcrConfig(env_name)
        build_number = os.getenv("GITHUB_RUN_NUMBER")
        version_to_deploy = os.getenv("VERSION_TO_DEPLOY")
        container_tag = get_container_tag(env_name, build_number, version_to_deploy)
        logger.info_green(f"container_tag: {container_tag}")
        full_docker_name = f"{ecr_config.ecr_url}/{ecr_config.docker_project}{svc_name}:{container_tag}"
        build_args=build_docker_args(runtime)
        docker_build(full_docker_name, build_args)
        docker_push(full_docker_name, ecr_config)
        if svc_name in REPLICATED_IMAGES:
            for docker_copy_destination in REPLICATED_IMAGES[svc_name]:
                full_docker_copy_destination = f"{ecr_config.ecr_url}/{docker_copy_destination}:{container_tag}"
                docker_copy(full_docker_name, full_docker_copy_destination, ecr_config)
        write_github_env(container_tag, "VERSION_TO_DEPLOY")
        write_github_summary(f":trophy: docker build and push done for {container_tag}")
        logger.info("End build_and_push.py")
    except Exception as e:
        exit_on_error_and_write_summary(f"error in build_and_push.main: {e}")


if __name__ == '__main__':
    main()
