import paramiko
import sys
import json
import logging
import unicodedata
logging.basicConfig(
    format='%(asctime)s %(levelname)-8s %(message)s',
    level=logging.INFO,
    datefmt='%Y-%m-%d %H:%M:%S'
        )

def create_remote(config, settings):
    type_r = config["remote_type"]
    if type_r == "sftp":
        import remote_sftp
        remote = remote_sftp.sftp_remote(config, settings)
    elif type_r == "local_dir":
        import remote_local_dir
        remote = remote_local_dir.local_dir_remote(config)
    return remote

def distribute_files(path_list, dest):
    for pathfile in path_list:
        if not str(pathfile).endswith('.dem'):
            continue
        log_msg = "uploading demo: " + str(pathfile)
        logging.info(log_msg)
        if not dest.put(pathfile, dest.path):
            log_msg = ''.join(["failed putting file: ", str(pathfile)])
            logging.warning(log_msg)
            sys.exit(1)

def load_config(config_file):
    try:
        with open(config_file) as infile:
            try:
                json_dict = json.load(infile)
                #logging.info(json_dict)
                return json_dict["remotes"], json_dict["jobs"], json_dict["settings"]
            except json.JSONDecodeError as e:
                logging.warning('exception caught: ', exc_info = True)
                sys.exit(1)
    except FileNotFoundError:
        logging.warning('exception caught: ', exc_info = True)
        sys.exit(1)

def main():
    #runs backups
    config_file = 'config_backups.json'
    if sys.argv[1:]:
        config_file = sys.argv[1]
    remotes, jobs, settings = load_config(config_file)
    for index, job in enumerate(jobs):
        src = create_remote(remotes[job["src"]], settings)
        dest = create_remote(remotes[job["dest"]], settings)
        dest2 = create_remote(remotes[job["dest2"]], settings)
        if index == 0:
            #delete old files (not very adaptable, cant handle dirs in dirs)
            dest.delete_remote_zips("/home/nonroot/backups/")
            dest2.delete_remote_zips("/home/autismbot5/backups/")
        if "backup_local" in job["job_name"]:
            zip_file_path = src.zip_local_directory(job)
            if not dest.put(zip_file_path, dest.path):
                log_msg = ''.join(["failed putting file: ", str(pathfile)])
                logging.warning(log_msg)
                sys.exit(1)
            if not dest2.put(zip_file_path, dest2.path):
                log_msg = ''.join(["failed putting file: ", str(pathfile)])
                logging.warning(log_msg)
                sys.exit(1)
            src.delete_local_zip(zip_file_path)
        elif "mysqldump" in job["job_name"]:
            src.remote_channel_command(job, "mysqldump")
            zipname = src.remote_channel_command(job, "tar_mysqldump")
            if zipname is None:
                logging.warning(f'failed zipping remote directory at job {job}')
                sys.exit(1)
            local_zip_path_name = src.get_remote_files(job, zipname)
            if local_zip_path_name is None:
                logging.warning(f'failed getting remote zip at job {job}')
                src.delete_remote_zip_temp(zipname)
                sys.exit(1)
            src.delete_remote_zip_temp(zipname)
            if not dest.put(local_zip_path_name, dest.path):
                logging.warning(f'failed putting local zip {local_zip_path_name} at job {job}')
                src.delete_local_zip(local_zip_path_name)
                sys.exit(1)
            if not dest2.put(local_zip_path_name, dest2.path):
                logging.warning(f'failed putting local zip {local_zip_path_name} at job {job}')
                src.delete_local_zip(local_zip_path_name)
                sys.exit(1)
            src.delete_local_zip(local_zip_path_name)
        elif "backup_remote" in job["job_name"]:
            zipname = src.remote_channel_command(job, "tar_recursive")
            if zipname is None:
                logging.warning(f'failed zipping remote directory at job {job}')
                sys.exit(1)
            local_zip_path_name = src.get_remote_files(job, zipname)
            if local_zip_path_name is None:
                logging.warning(f'failed getting remote zip at job {job}')
                src.delete_remote_zip_temp(zipname)
                sys.exit(1)
            src.delete_remote_zip_temp(zipname)
            if not dest.put(local_zip_path_name, dest.path):
                logging.warning(f'failed putting local zip {local_zip_path_name} at job {job}')
                src.delete_local_zip(local_zip_path_name)
                sys.exit(1)
            if not dest2.put(local_zip_path_name, dest2.path):
                logging.warning(f'failed putting local zip {local_zip_path_name} at job {job}')
                src.delete_local_zip(local_zip_path_name)
                sys.exit(1)
            src.delete_local_zip(local_zip_path_name)
        logging.info(('finished job: ', job))

if __name__ == '__main__':
    main()