# Path: pyani/download.py
# TAXONREGEX = re.compile(r"([0-9]\,?){1,}")
# class NCBIDownloadException(Exception):
# class FileExistsException(Exception):
# class PyaniIndexException(Exception):
# class ASMIDs(NamedTuple):
# class Classification(NamedTuple):
# class DLFileData(NamedTuple):
# class Hashstatus(NamedTuple):
# class DLStatus:
#     def __init__(self, msg: str = "Error downloading file from NCBI"):
#     def __init__(self, msg: str = "Specified file exists"):
#     def __init__(
#         self,
#         url: str,
#         hashurl: str,
#         outfname: Path,
#         outfhash: Path,
#         skipped: bool,
#         error: Optional[str] = None,
#     ):
# def last_exception() -> str:
# def make_asm_dict(taxon_ids: List[str], retries: int) -> Dict:
# def set_ncbi_email(email: str) -> None:
# def download_genome_and_hash(
#     outdir: Path,
#     timeout: int,
#     dlfiledata: DLFileData,
#     dltype: str = "RefSeq",
#     disable_tqdm: bool = False,
# ) -> namedlist:
# def entrez_retry(func):
#     def wrapper(*args, retries=1, **kwargs):
# def entrez_batch(func):
#     def wrapper(*args, expected=None, batchsize=None, **kwargs):
# def entrez_batched_webhistory(*args, **kwargs):
# def entrez_esearch(*args, **kwargs):
# def entrez_esummary(*args, **kwargs):
# def split_taxa(taxa: str) -> List[str]:
# def get_asm_uids(taxon_uid: str, retries: int) -> ASMIDs:
# def extract_filestem(esummary) -> str:
# def get_ncbi_esummary(asm_uid, retries, api_key=None) -> Tuple:
# def get_ncbi_classification(esummary) -> Classification:
# def compile_url(filestem: str, suffix: str, ftpstem: str) -> Tuple[str, str]:
# def download_url(
#     url: str, outfname: Path, timeout: int, disable_tqdm: bool = False
# ) -> None:
# def construct_output_paths(
#     filestem: str, suffix: str, outdir: Path
# ) -> Tuple[Path, Path]:
# def retrieve_genome_and_hash(
#     filestem: str,
#     suffix: str,
#     ftpstem: str,
#     outdir: Path,
#     timeout: int,
#     disable_tqdm: bool = False,
# ) -> DLStatus:
# def check_hash(fname: Path, hashfile: Path) -> Hashstatus:
# def extract_contigs(fname: Path, ename: Path) -> CompletedProcess:
# def create_labels(
#     classification: Classification, filestem: str, genomehash: str
# ) -> Tuple[str, str]:
# def create_hash(fname: Path) -> str:
# def extract_hash(hashfile: Path, name: str) -> str:
# 
# Path: pyani/pyani_files.py
# class PyaniFilesException(PyaniException):
# def get_fasta_files(dirname: Path = Path(".")) -> List[Path]:
# def get_fasta_paths(
#     dirname: Path = Path("."), extlist: Optional[List] = None
# ) -> List[Path]:
# def get_fasta_and_hash_paths(dirname: Path = Path(".")) -> List[Tuple[Path, Path]]:
# def get_input_files(dirname: Path, *ext) -> List[Path]:
# def get_sequence_lengths(fastafilenames: Iterable[Path]) -> Dict[str, int]:
# def read_hash_string(filename: Path) -> Tuple[str, str]:
# def read_fasta_description(filename: Path) -> str:
# def load_classes_labels(path: Path) -> Dict[str, str]:
# def collect_existing_output(dirpath: Path, program: str, args: Namespace) -> List[Path]:


import logging
import os
from argparse import Namespace
from pathlib import Path
from Bio import SeqIO
from pyani import download, pyani_files
    """Generate a file with the MD5 hash for each genome in an input directory.

    :param args:  Namespace, received command-line arguments
    :param logger:  logging object

    Identify the genome files in the input directory, and generate a single
    MD5 for each so that <genome>.fna produces <genome>.md5

    Genome files (FASTA) are identified from the file extension.
    """
    logger = logging.getLogger(__name__)

    # Get list of FASTA files in the input directory
    logger.info("Scanning directory %s for FASTA files", args.indir)
    fpaths = pyani_files.get_fasta_paths(args.indir)
    logger.info("Found FASTA files:\n" + "\n".join([f"\t{fpath}" for fpath in fpaths]))

    # Lists of class/label information
    classes = []
    labels = []

    # Create MD5 hash for each file, if needed
    for fpath in fpaths:
        hashfname = fpath.with_name(f"{fpath.name}.md5")
        if hashfname.is_file():
            logger.info("%s already indexed (using existing hash)", fpath)
            with open(hashfname, "r") as ifh:
                datahash = ifh.readline().split()[0]
        else:
            # Write an .md5 hash file

# Path: pyani/download.py
# TAXONREGEX = re.compile(r"([0-9]\,?){1,}")
# class NCBIDownloadException(Exception):
# class FileExistsException(Exception):
# class PyaniIndexException(Exception):
# class ASMIDs(NamedTuple):
# class Classification(NamedTuple):
# class DLFileData(NamedTuple):
# class Hashstatus(NamedTuple):
# class DLStatus:
#     def __init__(self, msg: str = "Error downloading file from NCBI"):
#     def __init__(self, msg: str = "Specified file exists"):
#     def __init__(
#         self,
#         url: str,
#         hashurl: str,
#         outfname: Path,
#         outfhash: Path,
#         skipped: bool,
#         error: Optional[str] = None,
#     ):
# def last_exception() -> str:
# def make_asm_dict(taxon_ids: List[str], retries: int) -> Dict:
# def set_ncbi_email(email: str) -> None:
# def download_genome_and_hash(
#     outdir: Path,
#     timeout: int,
#     dlfiledata: DLFileData,
#     dltype: str = "RefSeq",
#     disable_tqdm: bool = False,
# ) -> namedlist:
# def entrez_retry(func):
#     def wrapper(*args, retries=1, **kwargs):
# def entrez_batch(func):
#     def wrapper(*args, expected=None, batchsize=None, **kwargs):
# def entrez_batched_webhistory(*args, **kwargs):
# def entrez_esearch(*args, **kwargs):
# def entrez_esummary(*args, **kwargs):
# def split_taxa(taxa: str) -> List[str]:
# def get_asm_uids(taxon_uid: str, retries: int) -> ASMIDs:
# def extract_filestem(esummary) -> str:
# def get_ncbi_esummary(asm_uid, retries, api_key=None) -> Tuple:
# def get_ncbi_classification(esummary) -> Classification:
# def compile_url(filestem: str, suffix: str, ftpstem: str) -> Tuple[str, str]:
# def download_url(
#     url: str, outfname: Path, timeout: int, disable_tqdm: bool = False
# ) -> None:
# def construct_output_paths(
#     filestem: str, suffix: str, outdir: Path
# ) -> Tuple[Path, Path]:
# def retrieve_genome_and_hash(
#     filestem: str,
#     suffix: str,
#     ftpstem: str,
#     outdir: Path,
#     timeout: int,
#     disable_tqdm: bool = False,
# ) -> DLStatus:
# def check_hash(fname: Path, hashfile: Path) -> Hashstatus:
# def extract_contigs(fname: Path, ename: Path) -> CompletedProcess:
# def create_labels(
#     classification: Classification, filestem: str, genomehash: str
# ) -> Tuple[str, str]:
# def create_hash(fname: Path) -> str:
# def extract_hash(hashfile: Path, name: str) -> str:
# 
# Path: pyani/pyani_files.py
# class PyaniFilesException(PyaniException):
# def get_fasta_files(dirname: Path = Path(".")) -> List[Path]:
# def get_fasta_paths(
#     dirname: Path = Path("."), extlist: Optional[List] = None
# ) -> List[Path]:
# def get_fasta_and_hash_paths(dirname: Path = Path(".")) -> List[Tuple[Path, Path]]:
# def get_input_files(dirname: Path, *ext) -> List[Path]:
# def get_sequence_lengths(fastafilenames: Iterable[Path]) -> Dict[str, int]:
# def read_hash_string(filename: Path) -> Tuple[str, str]:
# def read_fasta_description(filename: Path) -> str:
# def load_classes_labels(path: Path) -> Dict[str, str]:
# def collect_existing_output(dirpath: Path, program: str, args: Namespace) -> List[Path]:


# Path: pyani/scripts/subcommands/subcmd_index.py
import logging
import os
from argparse import Namespace
from pathlib import Path
from Bio import SeqIO
from pyani import download, pyani_files

    """Generate a file with the MD5 hash for each genome in an input directory.

    :param args:  Namespace, received command-line arguments
    :param logger:  logging object

    Identify the genome files in the input directory, and generate a single
    MD5 for each so that <genome>.fna produces <genome>.md5

    Genome files (FASTA) are identified from the file extension.
    """
    logger = logging.getLogger(__name__)

    # Get list of FASTA files in the input directory
    logger.info("Scanning directory %s for FASTA files", args.indir)
    fpaths = pyani_files.get_fasta_paths(args.indir)
    logger.info("Found FASTA files:\n" + "\n".join([f"\t{fpath}" for fpath in fpaths]))

    # Lists of class/label information
    classes = []
    labels = []

    # Create MD5 hash for each file, if needed
    for fpath in fpaths:
        hashfname = fpath.with_name(f"{fpath.name}.md5")
        if hashfname.is_file():
            logger.info("%s already indexed (using existing hash)", fpath)
            with open(hashfname, "r") as ifh:
                datahash = ifh.readline().split()[0]
        else:
            # Write an .md5 hash file

            datahash = download.create_hash(fpath)