import os
import sys

def print_help():
    print("""
        Use this script to apply or delete Kubernetes deployments and services.

        Parameters: [deploy|delete|redeploy [microservice_name]]
        
        deploy ... applies all deployments and services from files
        delete ... deletes all deployments and services from files
        redeploy ... deletes and applies all microservices without deleting the database deployments
        microservice_name ... only apply/delete for one microservice
        """)


def get_microservice_name_from_path(path) -> str:
    '''
    Extracts the microservice name from the path.
    :param path: The path, eg. src\\data-hub\\stage-discovery-microservice\\deployment
    '''
    name = path.split(os.path.normpath('/'))[-2]
    
    if 'microservice' in name:
        name = '-'.join(name.split('-')[:-1])

    if name == 'message-broker':
        name = 'rabbit-mq'
    
    return name


def update_deployments_from_file(kube_command, paths, del_db=True) -> int:
    '''
    Applies the kube_command to all paths.
    Returns >0 if at least one error occured.

    :param kube_command: The command to use for kubectl
    :param paths: The list of paths to apply the kubectl command for 
    :param del_db: Also remove the corresponding db for the microservice

    :returns: >0, if an error occured
    '''
    exit_val = 0
    for path in paths:

        if del_db:
            exit_val += os.system(f"kubectl {kube_command} -f {path}")
        else:
            # use the single delete command to keep database (which is in same file)
            exit_val += delete_deployment(get_microservice_name_from_path(path))

    return exit_val


def delete_deployment(name) -> int:
    '''Delete a single deployment by name.'''
    exit_val = os.system(f"kubectl delete deployment {name}")
    return exit_val


if __name__ == '__main__':
    deployment_file_paths = []
    for p, _, f in os.walk('./'):
        for file in f:
            if 'deployment.yml' == file:
                deployment_file_paths.append(os.path.normpath(p))

    command = sys.argv[1] if len(sys.argv) > 1 else 'deploy'

    if command == 'help':
        print_help()
        sys.exit(0)

    img_name = None
    if len(sys.argv) > 2:
        img_name = sys.argv[2]
        deployment_file_paths = [p for p in deployment_file_paths if (img_name == get_microservice_name_from_path(p))]

    error_val = 0
    if command == 'delete' or command == 'redeploy':
        error_val += update_deployments_from_file('delete', deployment_file_paths, command=='delete')

    if command == 'deploy' or command == 'redeploy':
        error_val += update_deployments_from_file('apply', deployment_file_paths)
                

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