"""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 build_doc(options,  make_release=False):
    if make_release:
        options.make_tarball = True
        options.with_dot = True
        options.with_html_help = True
        options.with_uml_look = True
        options.open = False
        options.silent = True

    version = open('version', 'rt').read().strip()
    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,
        '%DOC_TOPDIR%': '',
        '%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],
        '%HTML_HELP%': yesno(options.with_html_help),
        '%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)
    run_doxygen(options.doxygen_path, 'doc/doxyfile', 'doc', is_silent=options.silent)
    if not options.silent:
        print(open(warning_log_path, 'r').read())
    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',
            'NEWS.txt',
            'version'
            ]
        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 build/doxygen.
    Optionaly makes a tarball of the documentation to dist/.

    Must be started in the project top directory.    
    """
    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('--with-html-help', dest="with_html_help", action='store_true', default=False,
        help="""Enable generation of Microsoft HTML HELP""")
    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()
