#!/usr/bin/env python3

import subprocess
from custom_operators.qarnot_utils import qarnot_general


def submit_app(port,
               host,
               task_uuid,
               job_uuid,
               path_remote_submit_script,
               path_app,
               path_config_qarnot,
               spark_driver_memory,
               spark_executor_memory,
               automatically_trust_ssh_host,
               path_local_logging_config,
               path_remote_logging_config,
               path_remote_log_sh_config,
               path_ssh_key,
               prepare_ssh_func,
               delete_task,
               arguments):

    """This function:
    - launches an app with Spark-submit, on the master of the cluster
    - 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)

        logger.debug("Start ssh communication with remote host")
        logger.debug("Automatically trust ssh host: "
                     + str(automatically_trust_ssh_host))
        if automatically_trust_ssh_host:
            # arguments must be a list to be appended to a list
            if arguments is None:
                arguments = []
            # subprocess.check_call takes a str list as arg
            arg_str = [str(item) for item in arguments]
            msg = ['ssh',
                   '-o', 'ServerAliveInterval=60',
                   '-o', 'CheckHostIP=no',
                   '-o', 'StrictHostKeyChecking=no',
                   '-p', str(port), 'root@' + host,
                   '/bin/bash', path_remote_submit_script,
                   path_app, spark_driver_memory, spark_executor_memory,
                   path_remote_logging_config,
                   path_remote_log_sh_config] + arg_str
            # add the private key path if needed
            if path_ssh_key is not None:
                qarnot_general.insert_in_list(msg, 1, '-i', path_ssh_key)
            # Add prepare_ssh_function if specified
            if prepare_ssh_func is not None:
                prepare_ssh_func(logger)
            subprocess.check_call(msg)
        else:
            logger.debug("automatically_trust_ssh_host is set to False, "
                         + "this is not supported by Airflow. Start again "
                         + "with automatically_trust_ssh_host set to True")

        # 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)
