#!/usr/bin/env python2.7
import sys, os, urllib2, argparse, re, cgi
from xml.etree import ElementTree as ET

def parsePubmed(doc, id):
    infoDict = dict()
    infoDict['url'] = "http://www.ncbi.nlm.nih.gov/pubmed/%s" % id
    attribList = ['PubDate', 'Source', 'Title', 'Volume', 'Issue', 'Pages', 'SO', 'CollectiveName']
    for element in doc:
        if element.tag != "DocSum":
            continue
        items = element.findall("Item")
        for i in items:
            if i.attrib['Name'] == 'AuthorList':
                infoDict['Authors'] = list()
                for j in i:
                    infoDict['Authors'].append(j.text)
                continue
            if i.attrib['Name'] in attribList:
                infoDict[i.attrib['Name']] = i.text

    return infoDict

def parsePmc(doc, id):
    infoDict = dict()
    infoDict['url'] = "http://www.ncbi.nlm.nih.gov/pmc/articles/%s" % id
    attribList = ['Title', 'PubDate', 'Journal', 'Volume', 'Issue', 'Pagination', 'CollectiveName']
    for node in doc.iter("ArticleId"):
        foundPubMedId = 0
        for child in node:
            if child.tag == "IdType" and child.text == "pmid":
                foundPubMedId = 1
            if foundPubMedId == 1 and child.tag == "Value":
                return parseInit(child.text) 
            
    sys.stderr.write("Unable to find pubmed id for pubmed central id: %s\n" % id)
    sys.exit()

def parseInit(id):
    urlbase = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?"
    db = "Pubmed"
    url = urlbase + "db=%s" % db + "&id=%s" % id
    if re.match("^PMC", id):
        db = "PMC"
        id = re.sub("PMC", "", id)
        url = urlbase + "db=%s" % db + "&id=%s&version=2.0" % id
    sys.stderr.write("Accessing %s\n" % url)
    fetch = urllib2.urlopen(url)
    doc = ET.XML(fetch.read())
    if db == "Pubmed":
        infoDict = parsePubmed(doc, id)
    elif db == "PMC":
        infoDict = parsePmc(doc, id)

    return infoDict

def htmlEscape(str):
    return cgi.escape(str).encode('ascii', 'xmlcharrefreplace')

def makeHtml(infoDict):
    authors = list()
    authcount = 0
    etal = 0
    if 'CollectiveName' in infoDict:
        authors.append(infoDict['CollectiveName'])
        authcount = 1
    for i in infoDict['Authors']:
        if authcount == 10:
            etal = 1
            break
        authors.append(i)
        authcount = authcount + 1
    sep = ", "
    authStr = sep.join(authors)
    authStr = htmlEscape(authStr)
    if etal:
        authStr = authStr + " <em>et al</em>"
    authStr = authStr + "."
    title = re.sub("\.$", "", infoDict['Title'])
    if 'Source' in infoDict:
        journal = infoDict['Source']
    elif 'Journal' in infoDict:
        journal = infoDict['Journal']
    if 'SO' in infoDict:
        dateStr = infoDict['SO']
    else:
        dateStr1 = infoDict['PubDate']
        dateStr = ""
        if 'Volume' in infoDict:
            dateStr = dateStr + ";%s" % infoDict['Volume']
        if 'Issue' in infoDict:
            dateStr = dateStr + "(%s)" % infoDict['Issue']
        if 'Pagination' in infoDict:
            dateStr = dateStr + "%s" % infoDict['Pagination']
        elif 'Pages' in infoDict:
            dateStr = dateStr + ":%s" %infoDict['Pages']
        dateStr = re.sub("\s+","", dateStr)
        dateStr = dateStr1 + dateStr
    if not re.search("\.$", dateStr):
        dateStr = dateStr + "."
    htmlStr = """
<p>
%s
<a href="%s" target="_blank">
%s</a>.
<em>%s</em>. %s
</p>
""" % (authStr, infoDict['url'], htmlEscape(title), htmlEscape(journal), dateStr)

    return htmlStr, authStr

def main():
    parser = argparse.ArgumentParser(
        prog='qaAddTrackReferences',
        description='Turns PubMed Ids and PubMedCentral Ids into GB formatted citations in html',
        epilog='example: qaAddTrackReferences PMC3039671 21347206'
        )
    parser.add_argument('ids', metavar='IDs', type=str, nargs='+', help='The list of PubMed and PubMedCentral Ids')

    if len(sys.argv) <= 1:
        parser.print_help()
    args = parser.parse_args(sys.argv[1:])
    ids = args.ids
    references = dict()

    for i in ids:
        infoDict = parseInit(i)
        html, authStr = makeHtml(infoDict)
        references[authStr] = html

    for i in sorted(references.keys()):
        print "%s" % references[i]

if __name__ == "__main__":
    main()
