# Path: augur/utils.py
# def get_parent_name_by_child_name_for_tree(tree):
#     '''
#     Return dictionary mapping child node names to parent node names
#     '''
#     parents = {}
#     for clade in tree.find_clades(order='level'):
#         for child in clade:
#             parents[child.name] = clade.name
#     return parents
# 
# def read_node_data(fnames, tree=None):
#     return NodeDataReader(fnames, tree).read()
# 
# def write_json(data, file_name, indent=(None if os.environ.get("AUGUR_MINIFY_JSON") else 2), include_version=True):
#     """
#     Write ``data`` as JSON to the given ``file_name``, creating parent directories
#     if necessary. The augur version is included as a top-level key "augur_version".
# 
#     Parameters
#     ----------
#     data : dict
#         data to write out to JSON
#     file_name : str
#         file name to write to
#     indent : int or None, optional
#         JSON indentation level. Default is `None` if the environment variable `AUGUR_MINIFY_JSON`
#         is truthy, else 1
#     include_version : bool, optional
#         Include the augur version. Default: `True`.
# 
#     Raises
#     ------
#     OSError
#     """
#     #in case parent folder does not exist yet
#     parent_directory = os.path.dirname(file_name)
#     if parent_directory and not os.path.exists(parent_directory):
#         try:
#             os.makedirs(parent_directory)
#         except OSError: #Guard against race condition
#             if not os.path.isdir(parent_directory):
#                 raise
# 
#     if include_version:
#         data["generated_by"] = {"program": "augur", "version": get_augur_version()}
# 
#     with open(file_name, 'w', encoding='utf-8') as handle:
#         json.dump(data, handle, indent=indent, sort_keys=True)
# 
# def get_json_name(args, default=None):
#     if args.output_node_data:
#         return args.output_node_data
#     else:
#         if default:
#             print("WARNING: no name for the output file was specified. Writing results to %s."%default, file=sys.stderr)
#             return default
#         else:
#             raise ValueError("Please specify a name for the JSON file containing the results.")


import sys
import pandas as pd
import numpy as np
import networkx as nx
from Bio import Phylo
from collections import defaultdict
from itertools import islice
from .utils import get_parent_name_by_child_name_for_tree, read_node_data, write_json, get_json_name


def get_reference_sequence_from_root_node(all_muts, root_name):
    # attach sequences to root
    ref = {}
    try:
        ref['nuc'] = list(all_muts[root_name]["sequence"])
    except:
        print("WARNING in augur.clades: nucleotide mutation json does not contain full sequences for the root node.")

    if "aa_muts" in all_muts[root_name]:
        try:
            ref.update({gene:list(seq) for gene, seq in all_muts[root_name]["aa_sequences"].items()})
        except:
            print("WARNING in augur.clades: amino acid mutation json does not contain full sequences for the root node.")

    return ref


def register_arguments(parser):
    parser.add_argument('--tree', help="prebuilt Newick -- no tree will be built if provided")
    parser.add_argument('--mutations', nargs='+', help='JSON(s) containing ancestral and tip nucleotide and/or amino-acid mutations ')
    parser.add_argument('--reference', nargs='+', help='fasta files containing reference and tip nucleotide and/or amino-acid sequences ')
    parser.add_argument('--clades', type=str, help='TSV file containing clade definitions by amino-acid')
    parser.add_argument('--output-node-data', type=str, help='name of JSON file to save clade assignments to')


def run(args):
    ## read tree and data, if reading data fails, return with error code
    tree = Phylo.read(args.tree, 'newick')

# Path: augur/utils.py
# def get_parent_name_by_child_name_for_tree(tree):
#     '''
#     Return dictionary mapping child node names to parent node names
#     '''
#     parents = {}
#     for clade in tree.find_clades(order='level'):
#         for child in clade:
#             parents[child.name] = clade.name
#     return parents
# 
# def read_node_data(fnames, tree=None):
#     return NodeDataReader(fnames, tree).read()
# 
# def write_json(data, file_name, indent=(None if os.environ.get("AUGUR_MINIFY_JSON") else 2), include_version=True):
#     """
#     Write ``data`` as JSON to the given ``file_name``, creating parent directories
#     if necessary. The augur version is included as a top-level key "augur_version".
# 
#     Parameters
#     ----------
#     data : dict
#         data to write out to JSON
#     file_name : str
#         file name to write to
#     indent : int or None, optional
#         JSON indentation level. Default is `None` if the environment variable `AUGUR_MINIFY_JSON`
#         is truthy, else 1
#     include_version : bool, optional
#         Include the augur version. Default: `True`.
# 
#     Raises
#     ------
#     OSError
#     """
#     #in case parent folder does not exist yet
#     parent_directory = os.path.dirname(file_name)
#     if parent_directory and not os.path.exists(parent_directory):
#         try:
#             os.makedirs(parent_directory)
#         except OSError: #Guard against race condition
#             if not os.path.isdir(parent_directory):
#                 raise
# 
#     if include_version:
#         data["generated_by"] = {"program": "augur", "version": get_augur_version()}
# 
#     with open(file_name, 'w', encoding='utf-8') as handle:
#         json.dump(data, handle, indent=indent, sort_keys=True)
# 
# def get_json_name(args, default=None):
#     if args.output_node_data:
#         return args.output_node_data
#     else:
#         if default:
#             print("WARNING: no name for the output file was specified. Writing results to %s."%default, file=sys.stderr)
#             return default
#         else:
#             raise ValueError("Please specify a name for the JSON file containing the results.")


# Path: augur/clades.py
import sys
import pandas as pd
import numpy as np
import networkx as nx
from Bio import Phylo
from collections import defaultdict
from itertools import islice
from .utils import get_parent_name_by_child_name_for_tree, read_node_data, write_json, get_json_name



def get_reference_sequence_from_root_node(all_muts, root_name):
    # attach sequences to root
    ref = {}
    try:
        ref['nuc'] = list(all_muts[root_name]["sequence"])
    except:
        print("WARNING in augur.clades: nucleotide mutation json does not contain full sequences for the root node.")

    if "aa_muts" in all_muts[root_name]:
        try:
            ref.update({gene:list(seq) for gene, seq in all_muts[root_name]["aa_sequences"].items()})
        except:
            print("WARNING in augur.clades: amino acid mutation json does not contain full sequences for the root node.")

    return ref


def register_arguments(parser):
    parser.add_argument('--tree', help="prebuilt Newick -- no tree will be built if provided")
    parser.add_argument('--mutations', nargs='+', help='JSON(s) containing ancestral and tip nucleotide and/or amino-acid mutations ')
    parser.add_argument('--reference', nargs='+', help='fasta files containing reference and tip nucleotide and/or amino-acid sequences ')
    parser.add_argument('--clades', type=str, help='TSV file containing clade definitions by amino-acid')
    parser.add_argument('--output-node-data', type=str, help='name of JSON file to save clade assignments to')


def run(args):
    ## read tree and data, if reading data fails, return with error code
    tree = Phylo.read(args.tree, 'newick')

    node_data = read_node_data(args.mutations, args.tree)