#!/usr/bin/env python

import argparse
import configparser
import logging
import os
import sys
import structlog

from pkg_resources import resource_filename

import cpo_pipeline

def main():
    """
    """
    
    script_name = os.path.basename(os.path.realpath(sys.argv[0]))
    parser = argparse.ArgumentParser(prog=script_name, description='')
    parser.add_argument('-v', '--version', action='version',
                        version='%(prog)s {}'.format(cpo_pipeline.__version__))
    subparsers = parser.add_subparsers()

    full_group = subparsers.add_parser('full')
    multi_group = subparsers.add_parser('multi')
    assembly_group = subparsers.add_parser('assembly')
    plasmids_group = subparsers.add_parser('plasmids')
    typing_group = subparsers.add_parser('typing')
    resistance_group = subparsers.add_parser('resistance')
    tree_group = subparsers.add_parser('tree')

    full_group.add_argument("-i", "--ID", dest="sample_id",
                            help="identifier of the isolate", required=True)
    full_group.add_argument("-e", "--expected-organism-taxid",
                            dest="expected_organism_ncbi_taxid",
                            help="Expected organism NCBI Taxonomy ID")
    full_group.add_argument("-1", "--R1", dest="reads1_fastq",
                            help="absolute file path forward read (R1)", required=True)
    full_group.add_argument("-2", "--R2", dest="reads2_fastq",
                            help="absolute file path to reverse read (R2)", required=True)
    full_group.add_argument("-o", "--outdir", dest="outdir", default='./',
                            help="absolute path to output folder")
    full_group.add_argument('-c', '--config', dest='config_file',
                            default=resource_filename('data', 'config.ini'),
                            help='Config File', required=False)
    full_group.set_defaults(func=cpo_pipeline.pipeline.main)

    
    multi_group.add_argument("-i", "--input", dest="input_file",
                             help="Multi-sample input file", required=True)
    multi_group.add_argument("-o", "--outdir", dest="outdir", default='./',
                             help="absolute path to output folder")
    multi_group.add_argument('-p', '--parallel', dest='parallel',
                             default=8,
                             help='Number of samples to process in parallel', required=False)
    multi_group.add_argument('-c', '--config', dest='config_file',
                             default=resource_filename('data', 'config.ini'),
                             help='Config File', required=False)
    multi_group.set_defaults(func=cpo_pipeline.pipeline.multi)


    assembly_group.add_argument("-i", "--ID", dest="sample_id",
                                help="identifier of the isolate", required=True)
    assembly_group.add_argument("-e", "--expected-organism-taxid",
                                dest="expected_organism_ncbi_taxid",
                                help="Expected organism NCBI Taxonomy ID")
    assembly_group.add_argument("-1", "--R1", dest="reads1_fastq",
                                help="absolute file path forward read (R1)", required=True)
    assembly_group.add_argument("-2", "--R2", dest="reads2_fastq",
                                help="absolute file path to reverse read (R2)", required=True)
    assembly_group.add_argument("-o", "--outdir", dest="outdir",
                                help="absolute path to output folder", required=True)
    assembly_group.add_argument("--mash-genomedb", dest="mash_genome_db",
                                help="absolute path to mash reference database")
    assembly_group.add_argument("--mash-plasmiddb", dest="mash_plasmid_db",
                                help="absolute path to mash reference database")
    assembly_group.add_argument("--mash-custom-plasmiddb", dest="mash_custom_plasmid_db",
                              help="absolute file path to directory of custom plasmid mash sketches",
                              required=False)
    assembly_group.add_argument('-c', '--config', dest='config_file',
                                default=resource_filename('data', 'config.ini'),
                                help='Config File', required=False)
    assembly_group.set_defaults(func=cpo_pipeline.assembly.pipeline.main)


    plasmids_group.add_argument("-i", "--ID", dest="sample_id",
                                help="identifier of the isolate", required=True)
    plasmids_group.add_argument("-1", "--R1", dest="reads1_fastq",
                                help="absolute file path forward read (R1)", required=True)
    plasmids_group.add_argument("-2", "--R2", dest="reads2_fastq",
                                help="absolute file path to reverse read (R2)", required=True)
    plasmids_group.add_argument("-o", "--outdir", dest="outdir", default='./',
                            help="absolute path to output folder")
    plasmids_group.add_argument("--mash-refseq-plasmid-db", dest="mash_refseq_plasmid_db",
                                help="absolute path to refseq mash reference database")
    plasmids_group.add_argument("--mash-custom-plasmid-db", dest="mash_custom_plasmid_db",
                              help="absolute file path to directory of custom plasmid mash sketches")
    plasmids_group.add_argument('-c', '--config', dest='config_file',
                                default=resource_filename('data', 'config.ini'),
                                help='Config File', required=False)
    plasmids_group.set_defaults(func=cpo_pipeline.plasmids.pipeline.main)


    resistance_group.add_argument("-i", "--ID", dest="sample_id",
                                  help="identifier of the isolate", required=True)
    resistance_group.add_argument("-o", "--outdir", dest="outdir",
                                  help="absolute path to output folder", required=True)
    resistance_group.add_argument("-a", "--assembly", dest="assembly",
                                  help="Path to assembly file.", required=True)
    resistance_group.add_argument("--card-json", dest="card_json",
                                  help="absolute path to card database (json format)")
    resistance_group.add_argument("--abricate-cpo-plamid-db", dest="abricate_cpo_plasmid_db",
                                  help="absolute path to abricate cpo plasmid db")
    resistance_group.add_argument("--abricate-datadir", dest="abricate_datadir",
                                  help="name of abricate database directory")
    resistance_group.add_argument('-c', '--config', dest='config_file',
                                  default=resource_filename('data', 'config.ini'),
                                  help='Config File', required=False)
    resistance_group.set_defaults(func=cpo_pipeline.resistance.pipeline.main)

    
    typing_group.add_argument("-i", "--ID", dest="sample_id",
                              help="identifier of the isolate", required=True)
    typing_group.add_argument("-o", "--outdir", dest="outdir",
                              help="absolute path to output folder", required=True)
    typing_group.add_argument("-a", "--assembly", dest="assembly",
                              help="Path to assembly file.", required=True)
    typing_group.add_argument("--mlst-scheme-map", dest="mlst_scheme_map_file",
                              help="absolute file path to mlst scheme")
    typing_group.add_argument('-c', '--config', dest='config_file',
                              default=resource_filename('data', 'config.ini'),
                              help='Config File', required=False)
    typing_group.set_defaults(func=cpo_pipeline.typing.pipeline.main)


    tree_group.add_argument("-i", "--input", dest="input_file",
                            help="Multi-sample input file", required=True)
    tree_group.add_argument("-r", "--reference", dest="reference",
                            help="Reference file (fasta or gbk)", required=True)
    tree_group.add_argument("-m", "--metadata", dest="metadata",
                            help="Metadata file", required=False)
    tree_group.add_argument("-o", "--outdir", dest="outdir",
                              help="absolute path to output folder", required=True)
    tree_group.add_argument("-d", "--resultdir", dest="result_dir",
                        help="Path to cpo-pipeline output folder")
    tree_group.add_argument('-c', '--config', dest='config_file',
                            default=resource_filename('data', 'config.ini'),
                            help='Config File', required=False)
    tree_group.set_defaults(func=cpo_pipeline.tree.pipeline.main)
    
    args = parser.parse_args()

    args.func(args)

if __name__ == '__main__':
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=logging.DEBUG,
    )

    structlog.configure_once(
        processors=[
            structlog.stdlib.add_log_level,
            structlog.processors.JSONRenderer()
        ],
        logger_factory=structlog.stdlib.LoggerFactory(),
        wrapper_class=structlog.stdlib.BoundLogger,
        context_class=structlog.threadlocal.wrap_dict(dict),
    )

    main()
