"""Script to generate doxygen documentation.
"""
from __future__ import print_function
from __future__ import unicode_literals
from devtools import tarball
from contextlib import contextmanager
import subprocess
import traceback
import re
import os
import sys
import shutil

@contextmanager
def cd(newdir):
    """
    http://stackoverflow.com/questions/431684/how-do-i-cd-in-python
    """
    prevdir = os.getcwd()
    os.chdir(newdir)
    try:
        yield
    finally:
        os.chdir(prevdir)

def find_program(*filenames):
    """find a program in folders path_lst, and sets env[var]
    @param filenames: a list of possible names of the program to search for
    @return: the full path of the filename if found, or '' if filename could not be found
"""
    paths = os.environ.get('PATH', '').split(os.pathsep)
    suffixes = ('win32' in sys.platform) and '.exe .com .bat .cmd' or ''
    for filename in filenames:
        for name in [filename+ext for ext in suffixes.split(' ')]:
            for directory in paths:
                full_path = os.path.join(directory, name)
                if os.path.isfile(full_path):
                    return full_path
    return ''

def do_subst_in_file(targetfile, sourcefile, dict):
    """Replace all instances of the keys of dict with their values.
    For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
    then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
    """
    with open(sourcefile, 'r') as f:
        contents = f.read()
    for (k,v) in list(dict.items()):
        v = v.replace('\\','\\\\')
        contents = re.sub(k, v, contents)
    with open(targetfile, 'w') as f:
        f.write(contents)

def getstatusoutput(cmd):
    """cmd is a list.
    """
    try:
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        output, _ = process.communicate()
        status = process.returncode
    except:
        status = -1
        output = traceback.format_exc()
    return status, output

def run_cmd(cmd, silent=False):
    """Raise exception on failure.
    """
    info = 'Running: %r in %r' %(' '.join(cmd), os.getcwd())
    print(info)
    sys.stdout.flush()
    if silent:
        status, output = getstatusoutput(cmd)
    else:
        status, output = subprocess.call(cmd), ''
    if status:
        msg = 'Error while %s ...\n\terror=%d, output="""%s"""' %(info, status, output)
        raise Exception(msg)

def assert_is_exe(path):
    if not path:
        raise Exception('path is empty.')
    if not os.path.isfile(path):
        raise Exception('%r is not a file.' %path)
    if not os.access(path, os.X_OK):
        raise Exception('%r is not executable by this user.' %path)

def run_doxygen(doxygen_path, config_file, working_dir, is_silent):
    assert_is_exe(doxygen_path)
    config_file = os.path.abspath(config_file)
    with cd(working_dir):
        cmd = [doxygen_path, config_file]
        run_cmd(cmd, is_silent)

def read_version():
    """Return the project version, e.g. '1.9.9', from include/json/version.h.
    """
    with open(os.path.join('include', 'json', 'version.h'), 'rt') as f:
        contents = f.read()
    match = re.search(r'^\s*#\s*define\s+JSONCPP_VERSION_STRING\s+"([^"]+)"',
                      contents, re.MULTILINE)
    if not match:
        raise Exception('JSONCPP_VERSION_STRING not found in include/json/version.h')
    return match.group(1)

def build_doc(options,  make_release=False):
    if make_release:
        options.make_tarball = True
        options.with_dot = True
        options.with_uml_look = True
        options.open = False
        options.silent = True

    version = read_version()
    output_dir = 'dist/doxygen' # relative to doc/doxyfile location.
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)
    top_dir = os.path.abspath('.')
    html_output_dirname = 'jsoncpp-api-html-' + version
    tarball_path = os.path.join('dist', html_output_dirname + '.tar.gz')
    warning_log_path = os.path.join(output_dir, '../jsoncpp-doxygen-warning.log')
    html_output_path = os.path.join(output_dir, html_output_dirname)
    def yesno(bool):
        return bool and 'YES' or 'NO'
    subst_keys = {
        '%JSONCPP_VERSION%': version,
        '%TOPDIR%': top_dir,
        '%HTML_OUTPUT%': os.path.join('..', output_dir, html_output_dirname),
        '%HAVE_DOT%': yesno(options.with_dot),
        '%DOT_PATH%': os.path.split(options.dot_path)[0],
        '%UML_LOOK%': yesno(options.with_uml_look),
        '%WARNING_LOG_PATH%': os.path.join('..', warning_log_path)
        }

    if os.path.isdir(output_dir):
        print('Deleting directory:', output_dir)
        shutil.rmtree(output_dir)
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)

    do_subst_in_file('doc/doxyfile', options.doxyfile_input_path, subst_keys)
    try:
        run_doxygen(options.doxygen_path, 'doc/doxyfile', 'doc', is_silent=options.silent)
    finally:
        # doxygen is configured with WARN_AS_ERROR, so the log explains failures.
        if os.path.isfile(warning_log_path):
            warnings = open(warning_log_path, 'r').read()
            if warnings:
                print('Doxygen warnings:')
                print(warnings)
    index_path = os.path.abspath(os.path.join('doc', subst_keys['%HTML_OUTPUT%'], 'index.html'))
    print('Generated documentation can be found in:')
    print(index_path)
    if options.open:
        import webbrowser
        webbrowser.open('file://' + index_path)
    if options.make_tarball:
        print('Generating doc tarball to', tarball_path)
        tarball_sources = [
            output_dir,
            'README.md',
            'LICENSE',
            ]
        tarball_basedir = os.path.join(output_dir, html_output_dirname)
        tarball.make_tarball(tarball_path, tarball_sources, tarball_basedir, html_output_dirname)
    return tarball_path, html_output_dirname

def main():
    usage = """%prog
    Generates doxygen documentation in dist/doxygen.
    Optionally makes a tarball of the documentation to dist/.

    Must be started in the project top directory.
    Fails if doxygen reports any warning.
    """
    from optparse import OptionParser
    parser = OptionParser(usage=usage)
    parser.allow_interspersed_args = False
    parser.add_option('--with-dot', dest="with_dot", action='store_true', default=False,
        help="""Enable usage of DOT to generate collaboration diagram""")
    parser.add_option('--dot', dest="dot_path", action='store', default=find_program('dot'),
        help="""Path to GraphViz dot tool. Must be full qualified path. [Default: %default]""")
    parser.add_option('--doxygen', dest="doxygen_path", action='store', default=find_program('doxygen'),
        help="""Path to Doxygen tool. [Default: %default]""")
    parser.add_option('--in', dest="doxyfile_input_path", action='store', default='doc/doxyfile.in',
        help="""Path to doxygen inputs. [Default: %default]""")
    parser.add_option('--no-uml-look', dest="with_uml_look", action='store_false', default=True,
        help="""Generates DOT graph without UML look [Default: False]""")
    parser.add_option('--open', dest="open", action='store_true', default=False,
        help="""Open the HTML index in the web browser after generation""")
    parser.add_option('--tarball', dest="make_tarball", action='store_true', default=False,
        help="""Generates a tarball of the documentation in dist/ directory""")
    parser.add_option('-s', '--silent', dest="silent", action='store_true', default=False,
        help="""Hides doxygen output""")
    parser.enable_interspersed_args()
    options, args = parser.parse_args()
    build_doc(options)

if __name__ == '__main__':
    main()
