#!/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

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

if sys.version_info < (3, 2):
    from ConfigParser import SafeConfigParser as ConfigParser
else:
    from configparser import ConfigParser

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

if sys.version_info.major == 2:
    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']
    }

    if arguments.gtk:
        dependent_packages['gdk-pixbuf-2.0'] = ['gdk-pixbuf']
        dependent_packages['gtk+-3.0'] = ['gtk3', 'gdk3']

    paths = []
    html_dir = os.path.join('share', 'gtk-doc', 'html')
    for package, modules in dependent_packages.items():
        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 = ConfigParser()
    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())

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

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

def build_gtkdoc_for_wkgtk(arguments):
    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)

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.')

    parser.add_argument('--gtk', action='store_true',
                        help='Build documentation for WebKitGTK')
    parser.add_argument('--wpe', action='store_true',
                        help='Build documentation for WPE')

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

    prepare_environment_for_gtkdoc_generation()

    if arguments.wpe:
        build_gtkdoc_for_wpe(arguments)
    elif arguments.gtk:
        build_gtkdoc_for_wkgtk(arguments)
    else:
        print('Please choose a WebKit port with --gtk or --wpe')
        sys.exit(1)
