#!/usr/bin/env python
import argparse
from pathlib import Path
from typing import Tuple, List

from metacarp import initialize_logging, logger, METACARP
from metacarp.app.utils import workflowutils


def parse_galaxy_args() -> Tuple[argparse.Namespace, List[str]]:
    """
    Parses the Galaxy arguments.
    :return: Parsed arguments
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--ilmn-in', nargs=4, action='append')
    parser.add_argument('--ont-in', nargs=2, action='append')
    parser.add_argument('--usual-suspects', action='append')
    parser.add_argument('--allergens', action='append')
    parser.add_argument('--dir-working', default=Path.cwd(), type=Path, help='Working directory')
    return parser.parse_known_args()


def _extract_dataset_name(fq_in: Path, name_orig: str) -> str:
    """
    Extracts the dataset name from the input FQ file.
    :param fq_in: Input FQ file
    :param name_orig: Galaxy name
    :return: Extracted name
    """
    return workflowutils.sanitize_input_name(name_orig, 'fastq.gz')


def main() -> None:
    """
    Runs the main script.
    :return: None
    """
    initialize_logging()
    logger.info(f'Running MetaCARP through Galaxy')
    args, unparsed_args = parse_galaxy_args()

    # Create input directory
    dir_in = args.dir_working / 'input'
    dir_in.mkdir(exist_ok=True)

    # Symlink the input files (Illumina)
    if args.ilmn_in is not None:
        logger.info(f'Creating symlinks for Illumina input ({len(args.ilmn_in)} datasets)')
        dir_ilmn = dir_in / 'ilmn'
        dir_ilmn.mkdir(exist_ok=True)
        for path_fw, path_rv, name_fw, name_rv in args.ilmn_in:
            try:
                basename_fw = workflowutils.sanitize_input_name(name_fw, 'fastq.gz')
                (dir_ilmn / basename_fw).symlink_to(path_fw)
            except FileExistsError:
                logger.debug(f"Symlink for '{name_fw}' already exists")
            try:
                basename_rv = workflowutils.sanitize_input_name(name_rv, 'fastq.gz')
                (dir_ilmn / basename_rv).symlink_to(path_rv)
            except FileExistsError:
                logger.debug(f"Symlink for '{name_rv}' already exists")
        unparsed_args.extend(['--ilmn-in', str(dir_ilmn.absolute())])

    # Symlink the input files (ONT)
    if args.ont_in is not None:
        logger.info(f'Creating symlinks for ONT input ({len(args.ont_in)} datasets)')
        dir_ont = dir_in / 'ont'
        dir_ont.mkdir(exist_ok=True)
        for path_ont, galaxy_name in args.ont_in:
            try:
                basename = workflowutils.sanitize_input_name(galaxy_name, 'fastq.gz')
                (dir_ont / basename).symlink_to(path_ont)
            except FileExistsError:
                logger.debug(f"Symlink for '{galaxy_name}' already exists")
        unparsed_args.extend(['--ont-in', str(dir_ont.absolute())])

    # Symlink the custom tsv files with usual suspects and allergens
    if args.usual_suspects is not None:
        logger.info(f'Creating symlink for custom list of usual suspects')
        dir_us = args.dir_working / 'usual_suspects.tsv'
        dir_us.symlink_to(args.usual_suspects)
        unparsed_args.extend(['--usual-suspects', str(dir_us.absolute())])

    if args.allergens is not None:
        logger.info(f'Creating symlink for custom list of allergens')
        dir_ag = args.dir_working / 'allergens.tsv'
        dir_ag.symlink_to(args.allergens)
        unparsed_args.extend(['--allergens', str(dir_ag.absolute())])

    # Run the main script
    workflow = METACARP(unparsed_args)
    workflow.run()


if __name__ == '__main__':
    main()
