#!/usr/bin/env python3


import sys
import argparse


def main():
    argparser = common_parser()
    args = argparser.parse_args()
    subcommand = args.subcommand
    if subcommand=='ucsctrack':
        from Mmint.ucsc import run
    if subcommand=='mdepth':
        from Mmint.mdepth import run
    if subcommand=='pca':
        from Mmint.PCAmeth import run
    if subcommand=='cluster':
        from Mmint.cluster import run
    if subcommand=='mcor':
        from Mmint.mCor import run
    if subcommand=='meth2chip':
        from Mmint.Meth2ChIP import run
    if subcommand=='multibw2Bed':
        from Mmint.multiBw2Bed import run
    if subcommand=='horizonalHeatmap':
        from Mmint.horizonalHeatmap import run
    if subcommand=='multiTracks':
        from Mmint.multiTracks import run
    if subcommand=='annotate':
        from Mmint.annotate import run
    if subcommand=='volcano':
        from Mmint.volcano import run
    if subcommand=='BedvsExpression':
        from Mmint.MethvsExpression import run
    if subcommand=='DepthVSReadnum':
        from Mmint.DepthvsReadsNum import run
    if subcommand=='CGratio':
        from Mmint.CGratio import run
    if subcommand=='HistonePeaks':
        from Mmint.HistonePeaks import run
    if subcommand=='UMRsCompare':
        from Mmint.UMRsCompare import run
    if subcommand=='UMRsExplain':
        from Mmint.UMRsExplain import run
    if subcommand=='scatter3d':
        from Mmint.scatter3d import run
    if subcommand=='OnlineAnalysis':
        from Mmint.OnlineAna import run 
    if subcommand==None:
        argparser.print_help()
        sys.exit()
    run(argparser)

def common_parser():
    argparser = argparse.ArgumentParser()
    subparsers = argparser.add_subparsers(dest="subcommand")
    add_mdepth_parsers(subparsers)
    add_pca_parsers(subparsers)
    add_mcor_parsers(subparsers)
    add_meth2chip_parsers(subparsers)
    add_multibw2bed_parsers(subparsers)
    add_horizonalHeatmap_parsers(subparsers)
    add_multiTracks_parsers(subparsers)
    add_annotate_parsers(subparsers)
    add_volcano_parsers(subparsers)
    add_cluster_parsers(subparsers)
    add_depthvsreadsnum_parsers(subparsers)
    add_methvsexpression_parsers(subparsers)
    add_qc_parsers(subparsers)
    add_HistonePeaks_parsers(subparsers)
    add_UMRsCompare_parsers(subparsers)
    add_UMRsExplain_parsers(subparsers)
    add_scatter3d_parsers(subparsers)
    add_onlineanalysis_parsers(subparsers)
    add_ucsctrack_parsers(subparsers)
    return argparser

def add_ucsctrack_parsers(s):
    parser = s.add_parser("ucsctrack",help="Forming a UCSC track for several files")
    '''
    -t  <str>   type 'peaks.bed', 'origin.bw', 'diff.bw', 'bw', 'bam','bb'
    -r  <str>   mm9 or hg18
    -s  <int>   scale eg.250
    -o  <str>   output file name. default: ucsc.type.txt
    '''
    parser.add_argument('-t','--type',help=r"File type. such as bw, bam, bb")
    parser.add_argument('-g','--genome',help=r"mm9 or mm10 or hg18 or hg19")
    parser.add_argument('-s','--scale',type=int,help=r"scale default=250",required=False,default=250)
    parser.add_argument('-o','--output',help="output file name. default=ucsc.type.txt",required=False,default="ucsc.type.txt")


def add_onlineanalysis_parsers(s):
    parser = s.add_parser("OnlineAnalysis",help="Doing online analysis using DAVID analysis api")
    parser.add_argument('-f','--file',help=r"Output file name",required=True,default='david.genelist.txt')
    parser.add_argument('-g','--genelist',help=r"Genelist file name. Use gene name or ensembl id")
    parser.add_argument('-t','--type',help=r"Gene list type: ensembl(0) or gene name(1)")


def add_methvsexpression_parsers(s):
    parser = s.add_parser("BedvsExpression",help="Bed file versus expression profile")
    parser.add_argument('-m','--methfile',help="Bed files describe sample",required=True)
    parser.add_argument('-r','--reference',help="select from hg19/mm10 or the TSS region self defined",required=True)
    parser.add_argument('-u','--upstream',help='TSS upstream (default 1000bp)',type=int,default=1000)
    parser.add_argument('-d','--downstream',help="TSS downstream (default 1000bp)",type=int,default=1000)
    parser.add_argument('-R','--RNAseq',help="Expression information, format(\\t==Tab): Genename\\tExpression_level",required=True)
    parser.add_argument('-ylab','--yaxislabel',help="Yaxis Label, default='Expression level'",default='Expression level')
    parser.add_argument('-xlab','--xaxislabel',help="Xaxis Label, default='Methylation level'",default='Methylation level')
    parser.add_argument('-o','--output',help="Prefix of the output PDF file.",required=True)

def add_volcano_parsers(s):
    parser = s.add_parser("volcano",help="Volcano plot for bedfile")
    parser.add_argument('-f','--file',help=r'DMR file. Format: chr start end ratio_difference p_value. Seperate:\t')
    parser.add_argument('-p','--p',help='cutoff p value',type=float)
    parser.add_argument('-o','--output',help="Prefix of the output PDF file.",required=True)


def add_annotate_parsers(s):
    parser = s.add_parser("annotate",help="annotate the bed file")
    parser.add_argument('-b','--bedfile',help="bedfile to annotate", metavar="FILE")
    parser.add_argument('-r','--reference',help="Bed files as reference to annotate.",nargs="*")
    parser.add_argument('-l','--label',help="Labels for reference bed files.", nargs='*')
    parser.add_argument('-o','--output',help="Prefix of the output PDF file.",required=True)

def add_multiTracks_parsers(s):
    parser = s.add_parser("multiTracks",help="This script will use bigwig and bed files as input and output pictures of multi-bigwig signals for each loci in the bedfiles. (similar with UCSC visualization tracks but can generated many automatically)")
    parser.add_argument('-b','--bigwig',help="input file (bw format)",nargs="*", metavar="FILE")
    parser.add_argument('-labels','--labels',help="labels for the input files",nargs="*", metavar="FILE")
    parser.add_argument('-bs','--binsize',help="bins size",default=100,type=int)
    parser.add_argument('-after','--downstream',help="downstream regions to plot",default=1000,type=int)
    parser.add_argument('-before','--upstream',help="upstream regions to plot",default=1000,type=int)
    parser.add_argument('-f','--file',help="file include all the regions to plot",metavar="FILE")
    parser.add_argument('-M','--marker',help="Information type of bigwig. Single base resolution(0)/region(1) resolution have different methods to calculate the average. For example: -M 1 0 1 means the first/third are region data. default: all samples are single base data.", nargs="*")


def add_depthvsreadsnum_parsers(s):
    parser = s.add_parser("DepthVSReadnum",help="This script will draw figure about depth and reads' number.")
    parser.add_argument('-m','--methfile',help="The output from mcall: *.G.bed",nargs="*", metavar="FILE")
    parser.add_argument('-l','--label',help="The labels",nargs="*", metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)

def add_horizonalHeatmap_parsers(s):
    parser = s.add_parser("horizonalHeatmap",help="This script will use bigwig and bed files as input and plot multiple types of signals distribution on interested locations (up/dnstream xxx bp) as a horizonal heatmap.")
    parser.add_argument('-bw','--bigwig',help="bigwig for the computeMatrix", nargs="*",metavar="FILE")
    parser.add_argument('-bed','--bed',help="the regions to plot", metavar="FILE")
    parser.add_argument('-after','--dnregions',help="downstream regions to plot",default=1000,type=int)
    parser.add_argument('-before','--upregions',help="upstream regions to plot",default=1000,type=int)
    parser.add_argument('-bs','--binsize',help="bins size to use", default=100,type=int)
    parser.add_argument('-m','--scaleregion',help="scale the input bed regions to certain length(bp)",default=1000,type=int)
    parser.add_argument('-L','--rowlabels',nargs="*",help="row labels for samples", metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)


def add_multibw2bed_parsers(s):
    parser = s.add_parser("multibw2Bed",help="This script generate the curve plot with multi-bigwig singal files against interested regions (bed file). Input files are multiple bigwig files and one bed (or multiple bed files) file.")
    parser.add_argument('-bw','--bigwig',help="bigwig or bed for the computeMatrix", nargs="*",metavar="FILE")
    parser.add_argument('-bed','--bed',help="the regions to plot", metavar="FILE", nargs="*")
    parser.add_argument('-after','--dnregions',help="downstream regions to plot", default=1000,type=int)
    parser.add_argument('-before','--upregions',help="upstream regions to plot", default=1000,type=int)
    parser.add_argument('-bs','--binsize',help="bins size to use", default=100,type=int)
    parser.add_argument('-m','--scaleregion',help="scale the input bed regions to certain length(bp)", default=1000,type=int)
    parser.add_argument('-g','--genome',help="Genome for transfering bed to bw. Not necessary if there's bed file in -bw. Select from: hg19,hg38,mm9,mm10",default="hg19")
    parser.add_argument('-L','--rowlabels',nargs="*",help="row labels for samples")
    parser.add_argument('-M','--marker',help="Information type of bigwig. Single base resolution(0)/region(1) resolution have different methods to calculate the average. For example: -M 1 0 1 means the first/third are region data. default: all samples are single base data.", nargs="*")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)
   

def add_meth2chip_parsers(s):
    parser = s.add_parser("meth2chip",help="This script will plot the average ChIP-seq signals at certain methylation ratio range; the input files are methylation ratio file (*.G.bed from mcall MOABS) and the ChIP-seq signals intensity file.")
    parser.add_argument('-m','--methfile',help="input methylation Ratio file (the output file from mcall) ", metavar="FILE")
    parser.add_argument('-p','--peakfile',help="input peaks signal file (bedgraph format) ", metavar="FILE")
    parser.add_argument('-a','--annotationfile',help="annotate peaks by bedfiles. e.g. Gene,Exon etc", metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)

def add_mcor_parsers(s):
    parser = s.add_parser("mcor",help="This script will generate the correlation matrix for all the samples and some basic statistics. It will also generate a plot with diagnol as histgram of methylation ratio for each sample; offdiagnal as pairwise density for methylation ratio.")
    parser.add_argument('-m','--methfile',help="The output from mcall",nargs='*', metavar="FILE")
    parser.add_argument('-l','--label',help="Label for methylation files", nargs='*')
    parser.add_argument('-g','--gridsize',help="Size of grid in scatterplot.default=20.",default=20,type=int)
    parser.add_argument('-c','--cov',type=int,help="minimal coverage of cpg sites for every sample,default=0",default=0)
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True) 

def add_mdepth_parsers(s):
    parser = s.add_parser("mdepth",help="This script will plot the Mean CpG methylation ratio and number of CpG sites under a series depth for multiple samples. The input file is the output file (*stat.txt) from mcall (MOABS).")
    parser.add_argument('-m','--methfile',help="The output *stat.txt from mcall",nargs="*",metavar="FILE")
    parser.add_argument('-l','--label',help="Labels for samples",nargs="*",metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)

def add_cluster_parsers(s):
    parser = s.add_parser("cluster",help="This script take methylation ratio matrix for multiplt samples as input to show the cluster result between samples.")
    parser.add_argument('-i','--inputfile',nargs='+',help='input file name',metavar="FILE")
    parser.add_argument('-N','--name',nargs='+',help="sample's name",required=True)
    parser.add_argument('-l','--linktype',help='linkage type for scipy, such as single,average,ward,cosine and so on.', default='single')
    parser.add_argument('-b','--bed',metavar="FILE",default='',help="If -b available, only cpgs in these regions will be selected in cluster.")
    parser.add_argument('-c','--cov',type=int,help="minimal coverage of cpg sites for every sample,default=0",default=0)
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)

def add_pca_parsers(s):
    parser = s.add_parser("pca",help="This script take methylation ratio matrix for multiple samples as input output a PCA plot.")
    parser.add_argument('-i','--inputfile',nargs='+',help="input bedfile name", metavar="FILE")
    parser.add_argument('-N','--name', nargs='+', help="the samples' names", required=True)
    parser.add_argument('-b','--bed',metavar="FILE",default='',help="If -b available, only cpgs in these regions will be selected in cluster.")
    parser.add_argument('-c','--cov',type=int,help="minimal coverage of cpg sites for every sample,default=0",default=0)
    parser.add_argument('-m','--method',help="pca or TSNE",default="pca")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)


def add_qc_parsers(s):
    parser = s.add_parser("CGratio",help="CG containing reads ratio")
    parser.add_argument('-b','--bamfile',help="bam file name", metavar="FILE")
    parser.add_argument('-g','--genome',help="Genome fasta file path")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)


def add_HistonePeaks_parsers(s):
    parser = s.add_parser("HistonePeaks",help="Classification of Peaks based on two histone markers")
    parser.add_argument('-bed','--bed',help="Two bedfiles representing two different histone modification.",nargs='*',metavar="FILE",required=True)
    parser.add_argument('-bw','--bigwig',help="bigwig for the computeMatrix", metavar="FILE",required=True)
    parser.add_argument('-after','--dnregions',help="downstream regions to plot",default=1000,type=int)
    parser.add_argument('-before','--upregions',help="upstream regions to plot",default=1000,type=int)
    parser.add_argument('-bs','--binsize',help="bins size to use", default=100,type=int)
    parser.add_argument('-L','--rowlabels',nargs="*",help="row labels for samples", metavar="FILE")
    parser.add_argument('-M','--methmarker',help="If bw file is methylation file, use -M.",action="store_true")
    parser.add_argument('-fb','--filterbed',help="Only use regions overlapped with given bed.")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)


def add_UMRsCompare_parsers(s):
    parser = s.add_parser("UMRsCompare",help="Compare UMRs length change between two conditions")
    parser.add_argument('-1','--UMRsFile1',help="UMRs file1 output from Mmint", metavar="FILE")
    parser.add_argument('-2','--UMRsFile2',help="UMRs file2 output from Mmint", metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True) 


def add_UMRsExplain_parsers(s):
    parser = s.add_parser("UMRsExplain",help="UMRs Explained/overlapped with histones")
    parser.add_argument('-i','--UMRsFile',help="UMRs file output from Mmint", metavar="FILE")
    parser.add_argument('-1','--annotateFile1',help="annotate bed file1", metavar="FILE")
    parser.add_argument('-2','--annotateFile2',help="annotate bed file2", metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)


def add_scatter3d_parsers(s):
    parser = s.add_parser("scatter3d",help="plot 3d scatter with 2d projection")
    parser.add_argument('-DMRs','--DMRs',help="the file include DMRs and diff mCG/CG value",metavar="FILE")
    parser.add_argument('-histRs','--DiffHistPeaks',help="the file include diff histone peaks and fold change",metavar="FILE")
    parser.add_argument('-o','--output',help="Prefix of the output PDF file", metavar="FILE",required=True)



if __name__=="__main__":
    main()

