#!/usr/bin/env python
# Copyright (C) 2011 Igalia S.L.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

from __future__ import print_function
from ConfigParser import SafeConfigParser

import argparse
import codecs
import glob
import gtkdoc
import logging
import os.path
import sys

top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..'))
sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'glib'))
import common

sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
sys.stderr = codecs.getwriter("utf-8")(sys.stderr)

def configure_logging(verbose):
    level = logging.DEBUG if verbose else logging.INFO
    logger = logging.getLogger('gtkdoc')
    logger.setLevel(level)
    handler = logging.StreamHandler()
    handler.setLevel(level)
    logger.addHandler(handler)
    if level == logging.DEBUG:
        handler.setFormatter(logging.Formatter('[%(asctime)s]  %(message)s'))
    else:
        handler.setFormatter(logging.Formatter('%(message)s'))

def get_gtkdoc_module_paths(cross_reference_deps):
    dependent_packages = {
        'glib-2.0' : ['glib', 'gobject', 'gio'],
        'libsoup-2.4' : ['libsoup-2.4'],
        'gdk-pixbuf-2.0': ['gdk-pixbuf'],
        'gtk+-3.0' : ['gtk3', 'gdk3']
    }

    paths = []
    html_dir = os.path.join('share', 'gtk-doc', 'html')
    for package, modules in dependent_packages.iteritems():
        prefix = common.prefix_of_pkg_config_file(package)
        if prefix is None:
            continue
        for module in modules:
            paths.append(os.path.join(prefix, html_dir, module))

    for local_dep in cross_reference_deps:
        paths.append(common.build_path('Documentation', local_dep, 'html'))
    return paths

def print_missing_api(generator):
    missing_api = generator.api_missing_documentation()
    if not missing_api:
        return
    print("\nThe following API are missing documentation:")
    for api in missing_api:
        print("\t{0}".format(api))

def files_to_ignore(source_dirs, headers_with_gtkdoc):
    """
    Find files to ignore during documentation generation. We assume that if an
    implementation file exists for a header with gtkdoc (say webkitfoo.cpp for
    webkitfoo.h) we shouldn't ignore that file. Currently this holds true for all
    of the WebKit project.
    """
    implementation_files = list(headers_with_gtkdoc)
    for header in headers_with_gtkdoc:
        def add_file_if_exists(filename):
            for dir in source_dirs:
                file = os.path.join(dir, filename)
                if os.path.isfile(file):
                    implementation_files.append(os.path.abspath(file))
        header_basename_without_extension = os.path.splitext(os.path.basename(header))[0]
        add_file_if_exists(header_basename_without_extension + ".cpp")
        add_file_if_exists(header_basename_without_extension + "Gtk.cpp")
        add_file_if_exists(header_basename_without_extension + ".c")

    def file_should_be_ignored(file):
        if os.path.splitext(file)[1] not in ['.h', '.c', '.cpp', '.cc']:
            return False # These files are ignored anyway.
        if not os.path.isfile(file):
            return True
        return os.path.abspath(file) not in implementation_files

    all_files = sum([[os.path.join(dir, file) for file in os.listdir(dir)] for dir in source_dirs], [])
    return filter(file_should_be_ignored, all_files)

def get_generator_for_config(config_file, virtual_root, cross_reference_deps = []):
    if not os.path.isfile(config_file):
        return None

    config = SafeConfigParser()
    config.read(config_file)
    module_name = config.sections()[0]
    pkgconfig_file = config.get(module_name, 'pkgconfig_file')

    if not os.path.isfile(pkgconfig_file):
        return None

    source_dirs = config.get(module_name, 'source_dirs').replace(';', ' ').split()
    headers = [os.path.abspath(f) for f in config.get(module_name, 'headers').replace(';', ' ').split()]
    return gtkdoc.PkgConfigGTKDoc(pkgconfig_file, {
        'decorator': config.get(module_name, 'decorator'),
        'deprecation_guard': config.get(module_name, 'deprecation_guard'),
        'library_path': common.library_build_path(),
        'virtual_root': virtual_root,
        'module_name': module_name,
        'namespace': config.get(module_name, 'namespace'),
        'doc_dir': config.get(module_name, 'doc_dir'),
        'output_dir': common.build_path('Documentation', module_name),
        'main_sgml_file': config.get(module_name, 'main_sgml_file'),
        'source_dirs': source_dirs,
        'headers': headers,
        'cflags': " ".join(config.get(module_name, 'cflags').split()),
        'cross_reference_deps': get_gtkdoc_module_paths(cross_reference_deps),
        'ignored_files': files_to_ignore(source_dirs, headers),
    })

def generate_doc(generator, skip_html):
    generator.generate(not skip_html)
    if generator.saw_warnings:
        print_missing_api(generator)
    return generator.saw_warnings

def rebase_doc(generator):
    try:
        generator.rebase_installed_docs()
    except Exception:
        print("Rebase did not happen, likely no documentation is present.")

def generate_documentation(generator):
    if not arguments.rebase:
        return generate_doc(generator, arguments.skip_html)

    rebase_doc(generator)
    return False

def prepare_environment_for_gtkdoc_generation():
    # We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
    # so that pkgconfig can properly resolve the libjavascriptcore dependency.
    pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
    os.environ['PKG_CONFIG_PATH'] = common.build_path('Source', 'JavaScriptCore')
    if pkg_config_path:
        os.environ['PKG_CONFIG_PATH'] += ':' + pkg_config_path

    # Newer versions of glib have deprecated g_type_init, so we need to disable
    # that warning when running gtkdoc-scanobj by overriding the CFLAGS we use
    # to compile it.
    cflags = os.environ.get('CFLAGS', '')
    cflags += ' -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'

    # In non-x86 architectures, when a pointer is cast to (void*) and
    # back, the compiler thinks that the alignment is random. Since
    # gtkdoc build is broken at any warning message, it is better to
    # silence these false positives.
    cflags += ' -Wno-cast-align'
    os.environ['CFLAGS'] = cflags

    # Paths from the GNUmakefile generated configuration files are relative to the build directory.
    os.chdir(common.build_path())

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Generate gtkdoc for WebKit.')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='Whether or not to run in verbose mode.')
    parser.add_argument('--rebase', action='store_true',
                        help='When specified, run the tool in rebase mode.')
    parser.add_argument('--skip-html', action='store_true',
                        help='Whether or not to skip HTML generation, which can be slow.')
    parser.add_argument('--virtual-root', type=str, default='',
                        help='A temporary installation directory which is used as the root ' + \
                             'where the actual installation prefix lives; this is mostly ' + \
                             'useful for packagers, and should be set to what is given to ' + \
                             'make install as DESTDIR.')

    arguments = parser.parse_args()
    configure_logging(arguments.verbose)

    prepare_environment_for_gtkdoc_generation()

    jsc_generator = get_generator_for_config(common.build_path('gtkdoc-jsc-glib.cfg'), arguments.virtual_root)
    if not jsc_generator:
        print("gtkdoc-jsc-glib.cfg does not exist! Skipping that documentation")
        sys.exit(1)
    saw_warnings = generate_documentation(jsc_generator)
    if saw_warnings:
        sys.exit(saw_warnings)

    webkitdom_generator = get_generator_for_config(common.build_path('gtkdoc-webkitdom.cfg'), arguments.virtual_root, [jsc_generator.module_name])
    if not webkitdom_generator:
        print("gtkdoc-webkitdom.cfg does not exist! Skipping that documentation")
        sys.exit(1)
    saw_warnings = generate_documentation(webkitdom_generator)
    if saw_warnings:
        sys.exit(saw_warnings)

    webkit2_generator = get_generator_for_config(common.build_path('gtkdoc-webkit2gtk.cfg'), arguments.virtual_root, [webkitdom_generator.module_name, jsc_generator.module_name])
    if not webkit2_generator:
        print("gtkdoc-webkit2gtk.cfg does not exist! Skipping that documentation")
        sys.exit(1)
    saw_warnings = generate_documentation(webkit2_generator)

    sys.exit(saw_warnings)
