#! /usr/bin/env python

from __future__ import print_function
import sys, os, re

## Parse arguments
import optparse
op = optparse.OptionParser()
#op.add_option("--embed", dest="EMBED", action="store_true", default=False, help="do not generate <html>, <head>, and <body> surrounging tags")
opts, args = op.parse_args()

## Get output filename
if not args:
    OUTFILE = "analyses.html"
    OUTDIR = "analyses"
else:
    OUTFILE = args[0]+".html"
    OUTDIR = args[0]
print("Using output file name '%s' and directory '%s'" % (OUTFILE, OUTDIR))


# ## Add the rivet Python module build dir(s) to the Python module path, then import
# pybuild = os.path.abspath(os.path.join(os.getcwd(), "..", "..", "pyext", "build"))
# pydirs = [os.path.join(pybuild, d) for d in os.listdir(pybuild)
#           if re.match(r"lib\..*-.*-%d\.%d" % (sys.version_info[0], sys.version_info[1]), d)]
# sys.path = pydirs + sys.path
import rivet

## Add info file locations
from glob import glob
dirpatt = os.path.join(os.getcwd(), "..", "..", "analyses", "plugin*")
for d in glob(dirpatt):
    rivet.addAnalysisDataPath(os.path.abspath(d))


## Get some strings of html ready.
from rivet.util import htmlify
foot = """\
</body>
</html>
"""
head = '''\
<html>
<head>
  <title>@TITLE@</title>
  <style>
    /* body { font-family:sans-serif; padding: 1em 1em 2em 2em; } */
    p, li { max-width:50em; }
    /* h2 { margin-left:-1em; margin-bottom:1.5em; } */
    /* h3 { color:#349; margin-top:2em; } */
    pre { line-height: 125%; }
  </style>
  <meta charset="utf-8">
  <script type="text/x-mathjax-config">MathJax.Hub.Config({ tex2jax: {inlineMath: [['$','$']]}, inTabOrder: false });</script>
  <script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</head>
<body>
  <h2>Rivet analyses reference</h2>
'''

## Check if code formatting is possible
try:
    import pygments
except:
    print("pygments formatter not found: code will be presented unformatted")

## Build analysis pages
can_analyses = rivet.AnalysisLoader.analysisNames()
all_analyses = rivet.AnalysisLoader.allAnalysisNames()
aliases = rivet.AnalysisLoader.analysisNameAliases()

## Remove any existing directory with name OUTDIR, make new one.
if os.path.exists(OUTDIR) and not os.path.realpath(OUTDIR) == os.getcwd():
    import shutil
    shutil.rmtree(OUTDIR)
try:
    os.makedirs(OUTDIR)
except:
    print("Error: failed to make new directory '%s'" % OUTDIR)
    sys.exit(1)

## Find analysis source files
ccpatt = os.path.join(os.getcwd(), "..", "..", "analyses", "plugin*", "*.cc")
ccfiles = glob(ccpatt)
#print(ccfiles)

summaries = {}
reentries = {}
pages = []
def anasort(a):
    "A sort-key function that should push SPIRES-named analyses to the end"
    return a if re.search(r"_S\d+", a) is None else "XXXXXXXXXXX_"+a
## Use list(...) ctor for 2.3 compatibility
for aname in sorted(all_analyses, key=anasort):
    page = ""
    page += "<h3 id='%s'>%s</h3>\n" % (aname, aname)

    ## Link to canonical if alias
    if aname not in can_analyses:
        #print("NONCANON", aname)
        if aname in aliases:
            page += '<p>Alias for analysis <a href="../{out}/{cana}.html">{cana}</a>.</p>\n'.format(out=OUTDIR, cana=aliases[aname])

    else:

        ## Summary and biblio links
        ana = rivet.AnalysisLoader.getAnalysis(aname)
        summaries[aname] = ana.summary()
        reentries[aname] = ana.reentrant()
        page += "<b>%s</b><br/>\n" %  htmlify(ana.summary())
        page += "<b>Experiment:</b> %s (%s)<br/>\n" % (ana.experiment(), ana.collider())
        if ana.inspireId():
            url = "https://inspirehep.net/literature/{}".format(ana.inspireId())
            page += "<b>Inspire ID:</b> <a href='%s'>%s</a><br/>\n" % (url, ana.inspireId())
        elif ana.spiresId():
            url = "https://inspirehep.net/literature?q={}".format(ana.spiresId())
            page += "<b>Spires ID:</b> <a href='%s'>%s</a><br/>\n" % (url, ana.spiresId())
        page += "<b>Status:</b> %s<br/>\n" % ana.status()

        ## Authors
        if ana.authors():
            page += "<b>Authors:</b>\n"
            page += "<ul>\n"
            for a in ana.authors():
                s = a
                import re
                if re.search(".* <.*@.*>", a):
                    name = " ".join(a.split()[:-1])
                    email = a.split()[-1].replace("<", "").replace(">", "")
                    #s = "<a href='mailto:%s'>%s</a>" % (email, name)
                    s = name
                page += "  <li>%s</li>\n" % htmlify(s)
            page += "</ul>\n"
        else:
            page += "<b>No authors listed</b>\n"

        ## References
        if ana.references():
            page += "<b>References:</b>\n"
            page += "<ul>\n"
            for r in ana.references():
                if r.startswith("arXiv:"):
                    code = r.split()[0].replace("arXiv:", "")
                    url = "http://arxiv.org/abs/" + code
                    page += "  <li>%s <a href='%s'>%s</a></li>\n" % ("arXiv:", htmlify(url), htmlify(code))
                elif r.startswith("doi:"):
                    code = r.replace("doi:", "")
                    url = "https://dx.doi.org/" + code
                    page += "  <li>%s <a href='%s'>%s</a></li>\n" % ("DOI:", htmlify(url), htmlify(code))
                elif r.startswith("ALICE-"):
                    code = r.replace("ALICE-", "")
                    url = "https://alice-publications.web.cern.ch/node/" + code
                    page += "  <li>%s <a href='%s'>%s</a></li>\n" % ("Public page:", htmlify(url), htmlify(r))
                elif r.startswith("ATLAS-"):
                    code = r.replace("ATLAS-", "")
                    url = "https://atlas.web.cern.ch/Atlas/GROUPS/PHYSICS/PAPERS/" + code
                    page += "  <li>%s <a href='%s'>%s</a></li>\n" % ("Public page:", htmlify(url), htmlify(r))
                elif r.startswith("CMS-"):
                    code = r.replace("CMS-", "")
                    url = "https://cms-results.web.cern.ch/cms-results/public-results/publications/" + code
                    page += "  <li>%s <a href='%s'>%s</a></li>\n" % ("Public page:", htmlify(url), htmlify(r))
                elif r.startswith("LHCb-"):
                    code = r.replace("PAPER-", "")
                    url = "https://lhcbproject.web.cern.ch/Publications/LHCbProjectPublic/%s.html" % r
                    page += "  <li>%s <a href='%s'>%s</a></li>\n" % ("Public page:", htmlify(url), htmlify(code))
                else:
                    page += "  <li>%s</li>\n" % htmlify(r)
            page += "</ul>\n"
        else:
            page += "<b>No references listed</b><br/>\n"

        ## Beams
        if ana.requiredBeams():
            def pid_to_str(pid):
                if pid == 11:
                    return "e-"
                elif pid == -11:
                    return "e+"
                elif pid == 2212:
                    return "p+"
                elif pid == -2212:
                    return "p-"
                elif pid == 10000:
                    return "*"
                else:
                    return str(pid)
            beamstrs = []
            for bp in ana.requiredBeams():
                beamstrs.append(pid_to_str(bp[0]) + " " + pid_to_str(bp[1]))
            page += "<b>Beams:</b> %s<br/>\n" % ", ".join(beamstrs)

        page += "<b>Beam energies:</b> "
        if ana.requiredEnergies():
            page += "; ".join(["(%0.1f, %0.1f)" % (epair[0], epair[1]) for epair in ana.requiredEnergies()])
            page += "&nbsp;GeV"
        else:
            page += "ANY"
        page += "<br/>\n"

        ## Run info
        if ana.runInfo():
            page += "<b>Run details:</b>\n"
            page += "<ul>\n"
            for l in ana.runInfo().split("\n*"):
                l = l.strip()
                if l.startswith("*"):
                    l = l[1:].strip()
                page += "  <li>%s</li>\n" % htmlify(l)
            page += "</ul>\n"
        else:
            page += "<ul>No run details listed</ul>\n"

        ## Description
        page += "\n<p>" + htmlify(ana.description(), para=True) + "</p>\n"

        ## Source code
        anaccfiles = [cc for cc in ccfiles if os.path.basename(cc).startswith(aname)]
        exactanaccfiles = [cc for cc in ccfiles if os.path.basename(cc) == aname+".cc"]
        if exactanaccfiles:
            anaccfiles = exactanaccfiles
        if anaccfiles:
            page += "<b>Source code:</b>\n"
            for cc in anaccfiles:
                page += "<b><kbd>%s</kbd></b>\n" % os.path.basename(cc)
                with open(cc, 'r') as f:
                    src = f.read()
                    if type(u'') != str:
                        src = src.decode("UTF-8")
                try:
                    from pygments.lexers import get_lexer_by_name
                    from pygments.formatters import get_formatter_by_name
                    lx = get_lexer_by_name("c++")
                    fm = get_formatter_by_name("html", linenos="table", noclasses=True)
                    page += pygments.highlight(src, lx, fm)
                except:
                    page += "<kbd>" + src.replace("\n", "<br/>\n") + "</kbd>"

    ## Write out to HTML analysis file
    ANAFILE = os.path.join(OUTDIR, aname+'.html')
    with open(ANAFILE, "wb") as f:
        outstr = head.replace("@TITLE@", "Rivet analysis reference: {} - {}" \
                              .format(aname, ana.summary())) + page + foot
        if type(u'') != str:
            outstr = unicode(outstr)
        f.write(outstr.encode("UTF-8"))


## Write out HTML toc file(s)
toc = "<h3>Contents</h3>\n"
toc += "<p>&reg; = analysis supports re-entrant finalize</p>\n"
toc += "<ul style=\"white-space: nowrap;\">\n"
for a in all_analyses: # TODO: change to only show can_analyses in ToC when all S-names are aliases
    ## NB. initial links designed for linking from inside the OUTDIR
    summ = "No summary"
    key = a if a in summaries else aliases[a]
    summ = htmlify(summaries[key])
    if reentries[key]:
        # print(a + " = REENTRANT")
        summ = "&reg;&nbsp;" + summ
        # summ = "R&nbsp;" + summ
    toc += '<li><a id="%s" href="../%s/%s.html">%s</a> &ndash; %s</li>\n' % (a, OUTDIR, a, a, summ)
toc += "</ul>\n"
outstr = head.replace("@TITLE@", "Rivet-analysis reference index") + toc + foot

## Index file in dir
with open(os.path.join(OUTDIR, "index.html"), "wb") as f:
    if type(u'') != str:
        outstr = unicode(outstr)
    f.write(outstr.encode("UTF-8"))

## External index file
outstr = outstr.replace("../%s" % OUTDIR, OUTDIR) #< correct link depth
if OUTFILE == "-":
    sys.stdout.write(outstr.encode("UTF-8"))
else:
    with open(OUTFILE, "wb") as f:
        f.write(outstr.encode("UTF-8"))
