import os
import sys
import threading
import boto3
from time import sleep
from aws.constants import ENVS, PROD_ENVS, STG_ENVS


def update_service(ms, env_name, ec2=False):
    global stop_execute
    # change only integration sx-core-dns-name of public to pub because of char limit:
    if ms == "sx-core-dns-public" and env_name == "integration":
        ms = "sx-core-dns-pub"
    # os.system(f"aws ecs update-service --cluster {env_name}-micro-services --service {ms} --force-new-deployment --enable-execute-command --task-definition {ms}-family-{env_name} --region {ecs_region}")
    if ec2 == "false":
        cluster_type = ""
    elif ec2:
        cluster_type = "ec2-"
    else:
        cluster_type = ""
    cluster_name = f"{env_name}-{cluster_type}micro-services"
    try:
        my_session = boto3.session.Session()
        client = my_session.client('ecs', region_name=ecs_region)
        response = client.describe_services(cluster=cluster_name, services=[ms])
        print(response)
        old_id = None
        try:
            message = response['services'][0]['events'][0]['message']
            if "has reached a steady state" in message:
                old_id = response['services'][0]['events'][0]['id']
        except Exception as e:
            print(f"no old id for ecs service {ms}:")
            print(f"cluster: {cluster_name}")
            print(f"error:\n{e}")
        sleep(5)
        if env_name in PROD_ENVS:
            env_name = "production"
        elif env_name in STG_ENVS:
            env_name = "staging"
        client.update_service(
            cluster=cluster_name,
            service=ms,
            taskDefinition=f"{ms}-family-{env_name}",
            forceNewDeployment=True,
            enableExecuteCommand=True
        )
        print(f"service {ms} updated")
        for _ in range(timeout):
            response = client.describe_services(
                cluster=cluster_name,
                services=[ms]
            )
            message = response['services'][0]['events'][0]['message']
            print(response['services'][0]['events'][0]['message'])
            sys.stdout.flush() 
            if "has reached a steady state" in message:
                if old_id:
                    if old_id == response['services'][0]['events'][0]['id']:
                        sleep(10)
                        continue
                print(f"ya-ba-da-ba-du the service {ms} has reached a steady state")
                return
            sleep(10)
        print(f"could not reach steady state on service {ms} on {env_name} in {timeout_minutes} minutes")
        stop_execute = True
    except Exception as e:
        print(f" error in update ecs service {ms}:")
        print(e)
        stop_execute = True


def run_ecs_update_in_threads(mss):
    for ms in mss:
        t = threading.Thread(target=update_service,
                             args=(ms, deploy_env, cluster_type))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()


deploy_env = os.getenv("ENV_NAME")
ecs_region = os.getenv('ECS_AWS_CLUSTER_REGION_LOCATION')
cluster_type = os.getenv('ECS_CLUSTER_TYPE', False)
timeout_minutes = int(os.getenv('UPDATE_SERVICE_TIMEOUT_MINUTES', 10))
timeout = timeout_minutes * 6
print(int(timeout))


if __name__ == '__main__':
    stop_execute = False
    ms = os.getenv('SVC_NAME')
    if ms == "p81_yarkon_gateway":
        ms = "yarkon-gateway"

    if ms == "saferx-backend":
        threads = []
        mss = ['saferx-backend', 'saferx-backend-cli']
        if deploy_env == 'solo':
            mss = ['saferx-backend']
        run_ecs_update_in_threads(mss)
    elif ms == "sx-core-dns":
        threads = []
        mss = ['sx-core-dns-private', 'sx-core-dns-public']
        run_ecs_update_in_threads(mss)
    else:
        update_service(ms, deploy_env, cluster_type)
    if stop_execute:
        exit(1)
