import os
import shutil
import sys
from typing import Dict

DOCKER_BUILD_NAME = "Dockerfile"
ROOT = './'
SOURCEPATH = f'{ROOT}src/'
DOCKERHUB_REPO_OWNER = "alexx882"


def print_help():
    print("""
        Use this script to build Docker images and upload them to Docker Hub.
        For the upload to work, the current user must be logged in on the Docker CLI and must have push access to the repositories.

        Parameters: [image_name]

        image_name ... only build this image
    """)


def get_dockerfile_paths_and_names() -> Dict[str, str]:
    paths = []
    for r, _, f in os.walk(SOURCEPATH):
        for filename in f:
            if DOCKER_BUILD_NAME == filename:
                paths.append(os.path.normpath(r))

    command_args = [{'path': path,
                     'name': str(path).split(os.path.normpath('/'))[-1]}
                    for path
                    in paths]

    return command_args


if __name__ == '__main__':
    p_image_name = None

    if len(sys.argv) == 2:
        arg = sys.argv[1]
        if arg == 'help':
            print_help()
            sys.exit(0)
        else:
            # parameter contains image name to be build
            p_image_name = arg

    command_args = get_dockerfile_paths_and_names()

    if p_image_name is not None:
        # filter for argument image name
        command_args = [x for x in command_args
                        if (p_image_name in x['name'])]

    error: int = 0
    res_str = []
    for command_arg in command_args:
        path = command_arg['path']
        image_name = f"{DOCKERHUB_REPO_OWNER}/{command_arg['name']}"

        # copy Dockerfile into root dir to have access to modules folder
        shutil.copy2(os.path.join(path, DOCKER_BUILD_NAME), ROOT)

        # build then remove Dockerfile
        exit_val = os.system(f"docker image build -t {image_name} {ROOT}")
        os.remove(os.path.join(ROOT, DOCKER_BUILD_NAME))

        res_str.append(f"{image_name} built with exit code {exit_val}")

        if exit_val != 0:
            error = exit_val

        else:
            # push created Docker image
            exit_val = os.system(f"docker push {image_name}")

            res_str.append(f"{image_name} pushed with exit code {exit_val}")
            if exit_val != 0:
                error = exit_val

    print(f"Found {len(command_args)} images")
    for s in res_str:
        print(s)

    sys.exit(1 if error > 0 else 0)
