import sys
import optparse
from erange import chksnp, getSNPs, getSNPGeneInfo, analyzego, getNovelSNPs, makeSNPtrack, rnaAToIFilter
from erange.commoncode import countDuplicatesInList, getConfigParser, getConfigOption


def main(argv=None):
    if not argv:
        argv = sys.argv

    usage = "usage: python %prog dbfile snpsfile genome rpkmfile [options]"

    parser = getParser(usage)
    (options, args) = parser.parse_args(argv[1:])

    if len(args) < 4:
        print usage
        sys.exit(1)

    dbfile = args[0]
    hitfile = args[1]
    genome = args[2]
    rpkmfilename = args[3]

    rnaEditing(dbfile, hitfile, genome, rpkmfilename, options)


def getParser(usage):
    parser = optparse.OptionParser(usage=usage)
    parser.add_option("--goprefix", dest="prefix")
    parser.add_option("--novelsnp", dest="novelsnpoutfilename")
    parser.add_option("--bedfile", dest="bedoutfilename")
    parser.add_option("--cache", type="int", dest="cachePages")
    parser.add_option("--snpDB", action="append", dest="snpDBList",
                      help="additional snp db files to check will be searched in order given")

    configParser = getConfigParser()
    section = "rnaEditing"
    prefix = getConfigOption(configParser, section, "prefix", None)
    novelsnpoutfilename = getConfigOption(configParser, section, "novelsnpoutfilename", None)
    bedoutfilename = getConfigOption(configParser, section, "bedoutfilename", None)
    cachePages = getConfigOption(configParser, section, "cachePages", None)

    parser.set_defaults(prefix=prefix, novelsnpoutfilename=novelsnpoutfilename, bedoutfilename=bedoutfilename,
                        cachePages=cachePages, snpDBList=[])

    return parser


def rnaEditing(dbfile, hitfile, genome, rpkmfilename, options):
    if options.cachePages is not None:
        doCache = True
    else:
        doCache = False

    # get the SNPs
    snpList = getSNPs.getSNPs(hitfile, 3, 0.25, doCache, options.cachePages, forceChr=True)

    # check for existing SNPs
    dbList = [dbfile]
    for dbFileName in options.snpDBList:
        dbList.append(dbFileName)

    snpPropertiesList = chksnp.chkSNP(dbList, snpList, options.cachePages)

    # get the neighboring genes
    geneInfoList = getSNPGeneInfo.getSNPGeneInfo(genome, snpPropertiesList, rpkmfilename, doCache, flankBP=10000)

    # filter out for the A-to-I events in the same direction as the genes
    filteredSNPs = rnaAToIFilter.rnaAToIFilter(geneInfoList)

    # count the number of different bases that have been called for each gene
    # pick a set of genes with a high number of sites (here 5)
    geneList = getGenesWithMultipleSNPs(filteredSNPs, minCount=5)

    if options.prefix is not None:
        analyzego.analyzeGO(genome, geneList, options.prefix, translateGene=True, fieldID=1)

    if options.novelsnpoutfilename is not None:
        getNovelSNPs.writeNovelSNPFile(genome, filteredSNPs, options.novelsnpoutfilename)

    if options.bedoutfilename is not None:
        makeSNPtrack.writeSNPsBedfile(filteredSNPs, "rnaEdit_sample", options.bedoutfilename)


def getGenesWithMultipleSNPs(snpList, minCount=1):
    geneList = []
    for snpEntry in snpList:
        geneList.append(snpEntry[11])

    duplicateCountList = countDuplicatesInList(geneList)

    geneList = []
    for (gene, count) in duplicateCountList:
        if count >= minCount:
            geneList.append(gene)

    return geneList


if __name__ == "__main__":
    main(sys.argv)