import os
from pathlib import Path

import yaml
import sys

def create_emapper_command(output_cmd_file, output_yaml, task_dict, query_file, prog_db_string, result_file_name, output_direction, threads):
    """
    :param output_cmd_file: path to output file fun_annot_by_emapper_on...md5sum.result -> ..result.emapper.annotations, ..result.emapper.seed_orthologs
    :param task_dict: dict #config['tasks'][task_no]
    :param query_file: seqs/all.faa
    :param prog_db_string: path to eggnog databases
    :param result_file_name: fun_annot_by_emapper_on...md5sum.result
    :param output_direction: path to output = '/task'
    :param threads: number of cpu to use
    """
    #no params
    if 'params' not in task_dict:
        task_dict['params'] = {}

    #empty query
    if os.path.getsize(query_file) == 0:
        for o in [output_cmd_file, output_yaml]:
            open(o, "w").close()
        cmd = ""

    #egnogg mapper
    else:
        task_dict['params']['data_dir'] = prog_db_string
        task_dict['params']['cpu'] = threads
        if task_dict['db_type'] == 'eggnog_v5':
            single_args = {'m', 'o'}
            task_dict['params']['o'] = result_file_name
            task_dict['params']['output_dir'] = output_direction
        else:
            single_args = {'m'}
            task_dict['params']['output'] = output_direction.joinpath(result_file_name)
        if 'm' not in task_dict['params'].keys():
            task_dict['params']['m'] = 'diamond'
        if task_dict['params']['m'] == 'diamond' and task_dict['db_type'] == 'eggnog_v5':
            size_all_seq_file = Path(query_file).stat().st_size
            if size_all_seq_file > 1024 * 1024 * 10:    # 10Mb
                block_size = round(1024 * 1024 * 10/size_all_seq_file, 1)
            else:
                block_size = 2.0
            task_dict['params']['block_size'] = block_size
        cmd = f"emapper.py -i {query_file} --override"
        cmd += " " + " ".join([f"--{x[0]} {x[1]}" if x[0] not in single_args else f"-{x[0]} {x[1]}"
                               for x in task_dict['params'].items()])

    # write cmd_file
    with open(output_cmd_file, "w") as handle:
        handle.write(cmd)
        handle.write("\n")

    #write yaml
    with open(output_yaml, "w") as handle:
        task = dict(task_dict)
        if 'params' in task:
            task['params'] = dict(task['params'])
        handle.write(yaml.dump(task))


def best_hit_emapper(fname):
    """
    opens emapper.result = emapper.annotation file and reads columns query (0) and seed_eggNOG_ortholog (1)
    """
    with open(fname, "r") as handle:
        best_hits = {}
        for line in handle:
            line = line.strip()
            if len(line) == 0 or line[0] == "#":
                continue
            fields = line.split("\t")
            # best_OG -> deprecated, use smallest from eggnog OGs, removed from best hits file
            best_hits[fields[0]] = fields[1]
    return best_hits


def write_emapper_best_hits(input, output):
    with open(output, "w") as handle:
        handle.write("\n".join([x[0] + "\t" + x[1] for x in best_hit_emapper(input).items()]))
