#!/usr/bin/env python3

import os
from custom_operators.qarnot_utils import qarnot_general


def sync_workers(task_uuid,
                 job_uuid,
                 path_config_qarnot,
                 snapshot_wait_sec,
                 path_local_logging_config,
                 delete_task):
    """This function should only be used when input bucket and output buckets \
    are the same. What it does:
    - updates the output bucket with latest changes
    - wait for the snapshot_wait_sec to make sure it is updated
    - synchronizes the input bucket with all machines of the cluster: master \
    and workers
    - manages the logs
    """

    try:
        # Configure the logger
        logger = qarnot_general.configure_logger(path_local_logging_config)
        logger.debug("Logger configured successfully")

        # Connection to Qarnot task
        conn = qarnot_general.qarnot_connection(path_config_qarnot, logger)
        task = conn.retrieve_task(task_uuid)
        job = conn.retrieve_job(job_uuid)

        if task.state == 'FullyExecuting':
            # sync ouptput files of the cluster servers with the output bucket
            task.instant()

            # necessary to wait for a few seconds
            logger.debug("Wait {} seconds before syncing"
                         .format(snapshot_wait_sec))
            task.wait(snapshot_wait_sec)

            # sync the content of the input bucket with the servers of the \
            # cluster
            logger.debug("Starts syncing the servers")
            task.update_resources()

            # necessary to wait for a few seconds that all workers are synced
            logger.debug("Wait {} seconds after syncing"
                         .format(snapshot_wait_sec))
            task.wait(snapshot_wait_sec)
        else:
            logger.warn("Task state was not 'FullyExecuting', "
                        + "no sync launched")

        # Display errors on failure and raise airflow exception
        qarnot_general.check_failure(task, job, delete_task, logger)

        # raise an airflow exception if the task was cancelled
        qarnot_general.check_cancellation(task, job, delete_task, logger)

    except Exception:
        qarnot_general.handle_error(logger, delete_task, task, job)
