# Path: augur/io.py
# def read_sequences(*paths, format="fasta"):
#     """Read sequences from one or more paths.
# 
#     Automatically infer compression mode (e.g., gzip, etc.) and return a stream
#     of sequence records in the requested format (e.g., "fasta", "genbank", etc.).
# 
#     Parameters
#     ----------
#     paths : list of str or Path-like objects
#         One or more paths to sequence files of any type supported by BioPython.
# 
#     format : str
#         Format of input sequences matching any of those supported by BioPython
#         (e.g., "fasta", "genbank", etc.).
# 
#     Yields
#     ------
#     Bio.SeqRecord.SeqRecord
#         Sequence record from the given path(s).
# 
#     """
#     for path in paths:
#         # Open the given path as a handle, inferring the file's compression.
#         # This way we can pass a handle to BioPython's SeqIO interface
#         # regardless of the compression mode.
#         with open_file(path) as handle:
#             sequences = Bio.SeqIO.parse(handle, format)
# 
#             for sequence in sequences:
#                 yield sequence
# 
# Path: augur/utils.py
# class AugurException(Exception):
# class InvalidTreeError(Exception):
# def is_vcf(filename):
# def read_vcf(filename):
# def myopen(fname, mode):
# def get_json_name(args, default=None):
# def ambiguous_date_to_date_range(uncertain_date, fmt, min_max_year=None):
# def read_metadata(fname, query=None, as_data_frame=False):
# def is_date_ambiguous(date, ambiguous_by="any"):
# def get_numerical_date_from_value(value, fmt=None, min_max_year=None):
# def get_numerical_dates(meta_dict, name_col = None, date_col='date', fmt=None, min_max_year=None):
# def read_tree(fname, min_terminals=3):
# def read_node_data(fnames, tree=None):
# def write_json(data, file_name, indent=(None if os.environ.get("AUGUR_MINIFY_JSON") else 2), include_version=True):
# def load_features(reference, feature_names=None):
# def read_config(fname):
# def read_lat_longs(overrides=None, use_defaults=True):
#     def add_line_to_coordinates(line):
# def read_colors(overrides=None, use_defaults=True):
# def write_VCF_translation(prot_dict, vcf_file_name, ref_file_name):
# def run_shell_command(cmd, raise_errors=False, extra_env=None):
# def first_line(text):
# def available_cpu_cores(fallback: int = 1) -> int:
# def nthreads_value(value):
# def get_parent_name_by_child_name_for_tree(tree):
# def annotate_parents_for_tree(tree):
# def json_to_tree(json_dict, root=True):
# def get_augur_version():
# def read_bed_file(bed_file):
# def read_mask_file(mask_file):
# def load_mask_sites(mask_file):
# def read_strains(*files, comment_char="#"):
#     T = None
#             T = Bio.Phylo.read(fname, fmt)
#                 T = None
# VALID_NUCLEOTIDES = { # http://reverse-complement.com/ambiguity.html
#     "A", "G", "C", "T", "U", "N", "R", "Y", "S", "W", "K", "M", "B", "V", "D", "H", "-",
#     "a", "g", "c", "t", "u", "n", "r", "y", "s", "w", "k", "m", "b", "v", "d", "h", "-"
# }


import os
import shlex
import shutil
import sys
import time
import uuid
import Bio
import numpy as np
        import json
from Bio.Seq import MutableSeq
from Bio import Phylo
from treetime.vcf_utils import read_vcf
from pathlib import Path
from .io import read_sequences
from .utils import run_shell_command, nthreads_value, shquote, load_mask_sites
        from string import ascii_uppercase as letters
    from Bio import SeqIO
    from Bio.SeqRecord import SeqRecord
    from Bio.Seq import Seq


def build_fasttree(aln_file, out_file, clean_up=True, nthreads=1, tree_builder_args=None):
    '''
    build tree using fasttree with parameters "-nt"
    '''
    log_file = out_file + ".log"

    fasttree = find_executable([
        # Search order is based on expected parallelism and accuracy
        # (double-precision versions).
        "FastTreeDblMP",
        "FastTreeDbl",
        "FastTreeMP",
        "fasttreeMP",   # Ubuntu lowercases
        "FastTree",
        "fasttree"
    ])

    # By default FastTree with OpenMP support uses all available cores.
    # However, it respects the standard OpenMP environment variable controlling
    # this as described at <http://www.microbesonline.org/fasttree/#OpenMP>.
    #
    # We always set it, regardless of it the found FastTree executable contains
    # "MP" in the name, because the generic "FastTree" or "fasttree" variants
    # might be OpenMP-enabled too.
    extra_env = {
        "OMP_NUM_THREADS": str(nthreads),
    }


# Path: augur/io.py
# def read_sequences(*paths, format="fasta"):
#     """Read sequences from one or more paths.
# 
#     Automatically infer compression mode (e.g., gzip, etc.) and return a stream
#     of sequence records in the requested format (e.g., "fasta", "genbank", etc.).
# 
#     Parameters
#     ----------
#     paths : list of str or Path-like objects
#         One or more paths to sequence files of any type supported by BioPython.
# 
#     format : str
#         Format of input sequences matching any of those supported by BioPython
#         (e.g., "fasta", "genbank", etc.).
# 
#     Yields
#     ------
#     Bio.SeqRecord.SeqRecord
#         Sequence record from the given path(s).
# 
#     """
#     for path in paths:
#         # Open the given path as a handle, inferring the file's compression.
#         # This way we can pass a handle to BioPython's SeqIO interface
#         # regardless of the compression mode.
#         with open_file(path) as handle:
#             sequences = Bio.SeqIO.parse(handle, format)
# 
#             for sequence in sequences:
#                 yield sequence
# 
# Path: augur/utils.py
# class AugurException(Exception):
# class InvalidTreeError(Exception):
# def is_vcf(filename):
# def read_vcf(filename):
# def myopen(fname, mode):
# def get_json_name(args, default=None):
# def ambiguous_date_to_date_range(uncertain_date, fmt, min_max_year=None):
# def read_metadata(fname, query=None, as_data_frame=False):
# def is_date_ambiguous(date, ambiguous_by="any"):
# def get_numerical_date_from_value(value, fmt=None, min_max_year=None):
# def get_numerical_dates(meta_dict, name_col = None, date_col='date', fmt=None, min_max_year=None):
# def read_tree(fname, min_terminals=3):
# def read_node_data(fnames, tree=None):
# def write_json(data, file_name, indent=(None if os.environ.get("AUGUR_MINIFY_JSON") else 2), include_version=True):
# def load_features(reference, feature_names=None):
# def read_config(fname):
# def read_lat_longs(overrides=None, use_defaults=True):
#     def add_line_to_coordinates(line):
# def read_colors(overrides=None, use_defaults=True):
# def write_VCF_translation(prot_dict, vcf_file_name, ref_file_name):
# def run_shell_command(cmd, raise_errors=False, extra_env=None):
# def first_line(text):
# def available_cpu_cores(fallback: int = 1) -> int:
# def nthreads_value(value):
# def get_parent_name_by_child_name_for_tree(tree):
# def annotate_parents_for_tree(tree):
# def json_to_tree(json_dict, root=True):
# def get_augur_version():
# def read_bed_file(bed_file):
# def read_mask_file(mask_file):
# def load_mask_sites(mask_file):
# def read_strains(*files, comment_char="#"):
#     T = None
#             T = Bio.Phylo.read(fname, fmt)
#                 T = None
# VALID_NUCLEOTIDES = { # http://reverse-complement.com/ambiguity.html
#     "A", "G", "C", "T", "U", "N", "R", "Y", "S", "W", "K", "M", "B", "V", "D", "H", "-",
#     "a", "g", "c", "t", "u", "n", "r", "y", "s", "w", "k", "m", "b", "v", "d", "h", "-"
# }


# Path: augur/tree.py
import os
import shlex
import shutil
import sys
import time
import uuid
import Bio
import numpy as np
        import json
from Bio.Seq import MutableSeq
from Bio import Phylo
from treetime.vcf_utils import read_vcf
from pathlib import Path
from .io import read_sequences
from .utils import run_shell_command, nthreads_value, shquote, load_mask_sites
        from string import ascii_uppercase as letters
    from Bio import SeqIO
    from Bio.SeqRecord import SeqRecord
    from Bio.Seq import Seq



def build_fasttree(aln_file, out_file, clean_up=True, nthreads=1, tree_builder_args=None):
    '''
    build tree using fasttree with parameters "-nt"
    '''
    log_file = out_file + ".log"

    fasttree = find_executable([
        # Search order is based on expected parallelism and accuracy
        # (double-precision versions).
        "FastTreeDblMP",
        "FastTreeDbl",
        "FastTreeMP",
        "fasttreeMP",   # Ubuntu lowercases
        "FastTree",
        "fasttree"
    ])

    # By default FastTree with OpenMP support uses all available cores.
    # However, it respects the standard OpenMP environment variable controlling
    # this as described at <http://www.microbesonline.org/fasttree/#OpenMP>.
    #
    # We always set it, regardless of it the found FastTree executable contains
    # "MP" in the name, because the generic "FastTree" or "fasttree" variants
    # might be OpenMP-enabled too.
    extra_env = {
        "OMP_NUM_THREADS": str(nthreads),
    }


    call = [fasttree, tree_builder_args, shquote(aln_file), "1>", shquote(out_file), "2>", shquote(log_file)]