#!python

import os
import sys
import warnings
from argparse import ArgumentParser

with warnings.catch_warnings():
    warnings.simplefilter("ignore")

    print("Loading AFQ libraries...")

    import logging

    import AFQ.utils.bin as afb

    logger = logging.getLogger("AFQ")
    logger.setLevel(level=logging.INFO)

usage = """
pyAFQ [OPTIONS] dwi t1 o_folder
pyAFQ download
pyAFQ qsiprep

The first form runs the pyAFQ tractometry pipeline on a single subject.

Two subcommands are also available, and take no further arguments:

    download   Fetch every template, atlas, and model pyAFQ may need and
               cache them locally, then exit. Run this once if you intend
               to use pyAFQ on a machine without internet access, or to
               build a Docker image.

    qsiprep    Write default JSON configuration files into the current
               working directory and exit. These can be used to define a
               pyAFQ recon workflow in qsiprep; no pipeline is run.

General options:

    -h, --help       Show this help message and arguments.
    -v, --verbose    Verbose logging.
    -d, --dry-run    Print the recognized arguments without running pyAFQ.
    -c, --call       AFQ.api attribute to get. Defaults to 'all', which
                     runs the entire tractometry pipeline.
"""


def parse_cli(arg_dict):
    if len(sys.argv) == 2 and sys.argv[1] == "download":
        logger.info("Downloading templates...")
        download_templates()
        exit()
    elif len(sys.argv) >= 2 and sys.argv[1] == "qsiprep":
        logger.info("Generating JSON config for qsiprep...")
        afb.generate_json(os.getcwd(), logger=logger)
        exit()

    cli_parser = ArgumentParser(usage=usage)

    cli_parser.add_argument(dest="dwi", action="store", help="Path to DWI data file")

    cli_parser.add_argument(
        dest="t1",
        action="store",
        help=(
            "Path to T1-weighted image file. "
            "Must already be registered to the "
            "DWI data, though not resampled."
        ),
    )

    cli_parser.add_argument(
        dest="o_folder", action="store", help="Path to output folder"
    )

    cli_parser.add_argument(
        "--bval",
        dest="bval",
        action="store",
        default=False,
        help=(
            "Path to bval file. "
            "If none, the dwi data "
            "file path will be used to find it."
        ),
    )

    cli_parser.add_argument(
        "--bvec",
        dest="bvec",
        action="store",
        default=False,
        help=(
            "Path to bvec file. "
            "If none, the dwi data "
            "file path will be used to find it."
        ),
    )

    cli_parser.add_argument(
        "-v",
        "--verbose",
        dest="verbose",
        action="store_true",
        default=False,
        help="Verbose when reading TOML file",
    )

    cli_parser.add_argument(
        "-d",
        "--dry-run",
        dest="dry_run",
        action="store_true",
        default=False,
        help="Perform a dry run - prints recognized"
        + " arguments without running pyAFQ",
    )

    cli_parser.add_argument(
        "-c",
        "--call",
        dest="to_call",
        action="store",
        default="all",
        help="AFQ.api attribute to get using the specified config file."
        + " Defaults to 'all', which will perform the entire"
        + " tractometry pipeline.",
    )

    for key_, args in arg_dict.items():
        if key_ == "AFQ_desc" or key_ == "BIDS_PARAMS":
            continue
        for arg, arg_info in args.items():
            cli_parser.add_argument(
                f"--{arg}",
                dest=arg,
                action="store",
                default=arg_info["default"],
                help=arg_info["desc"],
            )

    return cli_parser.parse_args()


def download_templates():
    import AFQ.data.fetch as afd

    afd.read_templates()
    afd.read_pediatric_templates()
    afd.read_callosum_templates()
    afd.read_cp_templates()
    afd.read_or_templates()
    afd.read_ar_templates()
    afd.read_slf_templates()
    afd.read_callosum_templates()
    afd.fetch_synthseg_models()
    afd.read_mni_template(mask=True, weight="T2w")
    afd.read_mni_template(mask=True, weight="T1w")
    afd.read_org800_templates()
    afd.fetch_brainchop_models()


if __name__ == "__main__":
    arg_dict = afb.func_dict_to_arg_dict(logger=logger)
    args = parse_cli(arg_dict)

    afb.parse_config_run_afq(
        args.dwi,
        args.bval,
        args.bvec,
        args.t1,
        args.o_folder,
        arg_dict,
        args,
        to_call=args.to_call,
        verbose=args.verbose,
        dry_run=args.dry_run,
        logger=logger,
    )
