# 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

import errno
import logging
import os
import os.path
import subprocess
import sys


class GTKDoc(object):

    """Class that controls a gtkdoc run.

    Each instance of this class represents one gtkdoc configuration
    and set of documentation. The gtkdoc package is a series of tools
    run consecutively which converts inline C/C++ documentation into
    docbook files and then into HTML. This class is suitable for
    generating documentation or simply verifying correctness.

    Keyword arguments:
    output_dir         -- The path where gtkdoc output should be placed. Generation
                          may overwrite file in this directory. Required.
    module_name        -- The name of the documentation module. For libraries this
                          is typically the library name. Required if not library path
                          is given.
    source_dirs        -- A list of paths to directories of source code to be scanned.
                          Required if headers is not specified.
    ignored_files      -- A list of filenames to ignore in the source directory. It is
                          only necessary to provide the basenames of these files.
                          Typically it is important to provide an updated list of
                          ignored files to prevent warnings about undocumented symbols.
    headers            -- A list of paths to headers to be scanned. Required if source_dirs
                          is not specified.
    namespace          -- The library namespace.
    decorator          -- If a decorator is used to unhide certain symbols in header
                          files this parameter is required for successful scanning.
                          (default '')
    deprecation_guard  -- gtkdoc tries to ensure that symbols marked as deprecated
                          are encased in this C preprocessor define. This is required
                          to avoid gtkdoc warnings. (default '')
    cflags             -- This parameter specifies any preprocessor flags necessary for
                          building the scanner binary during gtkdoc-scanobj. Typically
                          this includes all absolute include paths necessary to resolve
                          all header dependencies. (default '')
    ldflags            -- This parameter specifies any linker flags necessary for
                          building the scanner binary during gtkdoc-scanobj. Typically
                          this includes "-lyourlibraryname". (default '')
    library_path       -- This parameter specifies the path to the directory where you
                          library resides used for building the scanner binary during
                          gtkdoc-scanobj. (default '')

    doc_dir            -- The path to other documentation files necessary to build
                          the documentation. This files in this directory as well as
                          the files in the 'html' subdirectory will be copied
                          recursively into the output directory. (default '')
    main_sgml_file     -- The path or name (if a doc_dir is given) of the SGML file
                          that is the considered the main page of your documentation.
                          (default: <module_name>-docs.sgml)
    version            -- The version number of the module. If this is provided,
                          a version.xml file containing the version will be created
                          in the output directory during documentation generation.

    interactive        -- Whether or not errors or warnings should prompt the user
                          to continue or not. When this value is false, generation
                          will continue despite warnings. (default False)

    virtual_root       -- 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.
    """

    def __init__(self, args):

        # Parameters specific to scanning.
        self.module_name = ''
        self.source_dirs = []
        self.headers = []
        self.ignored_files = []
        self.namespace = ''
        self.decorator = ''
        self.deprecation_guard = ''

        # Parameters specific to gtkdoc-scanobj.
        self.cflags = ''
        self.ldflags = ''
        self.library_path = ''

        # Parameters specific to generation.
        self.output_dir = ''
        self.doc_dir = ''
        self.main_sgml_file = ''

        # Parameters specific to gtkdoc-fixxref.
        self.cross_reference_deps = []

        self.interactive = False

        self.logger = logging.getLogger('gtkdoc')

        for key, value in iter(args.items()):
            setattr(self, key, value)

        if not getattr(self, 'output_dir'):
            raise Exception('output_dir not specified.')
        if not getattr(self, 'module_name'):
            raise Exception('module_name not specified.')
        if not getattr(self, 'source_dirs') and not getattr(self, 'headers'):
            raise Exception('Neither source_dirs nor headers specified.' % key)

        # Make all paths absolute in case we were passed relative paths, since
        # we change the current working directory when executing subcommands.
        self.output_dir = os.path.abspath(self.output_dir)
        self.source_dirs = [os.path.abspath(x) for x in self.source_dirs]
        self.headers = [os.path.abspath(x) for x in self.headers]
        if self.library_path:
            self.library_path = os.path.abspath(self.library_path)

        if not self.main_sgml_file:
            self.main_sgml_file = self.module_name + "-docs.sgml"

    def generate(self, html=True):
        self.saw_warnings = False

        self._copy_doc_files_to_output_dir(html)
        self._write_version_xml()
        self._run_gtkdoc_scan()
        self._run_gtkdoc_scangobj()
        self._run_gtkdoc_mkdb()

        if not html:
            return

        self._run_gtkdoc_mkhtml()
        self._run_gtkdoc_fixxref()

    def _delete_file_if_exists(self, path):
        if not os.access(path, os.F_OK | os.R_OK):
            return
        self.logger.debug('deleting %s', path)
        os.unlink(path)

    def _create_directory_if_nonexistent(self, path):
        try:
            os.makedirs(path)
        except OSError as error:
            if error.errno != errno.EEXIST:
                raise

    def _raise_exception_if_file_inaccessible(self, path):
        if not os.path.exists(path) or not os.access(path, os.R_OK):
            raise Exception("Could not access file at: %s" % path)

    def _output_has_warnings(self, outputs):
        for output in outputs:
            if output and output.find('warning'):
                return True
        return False

    def _ask_yes_or_no_question(self, question):
        if not self.interactive:
            return True

        question += ' [y/N] '
        answer = None
        while answer != 'y' and answer != 'n' and answer != '':
            answer = raw_input(question).lower()
        return answer == 'y'

    def _run_command(self, args, env=None, cwd=None, print_output=True, ignore_warnings=False):
        if print_output:
            self.logger.info("Running %s", args[0])
        self.logger.debug("Full command args: %s", str(args))

        process = subprocess.Popen(args, env=env, cwd=cwd,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        stdout, stderr = [b.decode("utf-8") for b in process.communicate()]

        if print_output:
            if stdout:
                try:
                    sys.stdout.write(stdout.encode("utf-8"))
                except UnicodeDecodeError:
                    sys.stdout.write(stdout)
            if stderr:
                try:
                    sys.stderr.write(stderr.encode("utf-8"))
                except UnicodeDecodeError:
                    sys.stderr.write(stderr)

        if process.returncode != 0:
            raise Exception('%s produced a non-zero return code %i'
                             % (args[0], process.returncode))

        if not ignore_warnings and ('warning' in stderr or 'warning' in stdout):
            self.saw_warnings = True
            if not self._ask_yes_or_no_question('%s produced warnings, '
                                                'try to continue?' % args[0]):
                raise Exception('%s step failed' % args[0])

        return stdout.strip()

    def _copy_doc_files_to_output_dir(self, html=True):
        if not self.doc_dir:
            self.logger.info('Not copying any files from doc directory,'
                             ' because no doc directory given.')
            return

        def copy_file_replacing_existing(src, dest):
            if os.path.isdir(src):
                self.logger.debug('skipped directory %s',  src)
                return
            if not os.access(src, os.F_OK | os.R_OK):
                self.logger.debug('skipped unreadable %s', src)
                return

            self._delete_file_if_exists(dest)

            self.logger.debug('created %s', dest)
            try:
                os.link(src, dest)
            except OSError:
                os.symlink(src, dest)

        def copy_all_files_in_directory(src, dest):
            for path in os.listdir(src):
                copy_file_replacing_existing(os.path.join(src, path),
                                             os.path.join(dest, path))

        self.logger.info('Copying template files to output directory...')
        self._create_directory_if_nonexistent(self.output_dir)
        copy_all_files_in_directory(self.doc_dir, self.output_dir)

        if not html:
            return

        self.logger.info('Copying HTML files to output directory...')
        html_src_dir = os.path.join(self.doc_dir, 'html')
        html_dest_dir = os.path.join(self.output_dir, 'html')
        self._create_directory_if_nonexistent(html_dest_dir)

        if os.path.exists(html_src_dir):
            copy_all_files_in_directory(html_src_dir, html_dest_dir)

    def _write_version_xml(self):
        if not self.version:
            self.logger.info('No version specified, so not writing version.xml')
            return

        version_xml_path = os.path.join(self.output_dir, 'version.xml')
        src_version_xml_path = os.path.join(self.doc_dir, 'version.xml')

        # Don't overwrite version.xml if it was in the doc directory.
        if os.path.exists(version_xml_path) and \
           os.path.exists(src_version_xml_path):
            return

        output_file = open(version_xml_path, 'w')
        output_file.write(self.version)
        output_file.close()

    def _ignored_files_basenames(self):
        return ' '.join([os.path.basename(x) for x in self.ignored_files])

    def _run_gtkdoc_scan(self):
        args = ['gtkdoc-scan',
                '--module=%s' % self.module_name,
                '--rebuild-types']

        if not self.headers:
            # Each source directory should be have its own "--source-dir=" prefix.
            args.extend(['--source-dir=%s' % path for path in self.source_dirs])

        if self.decorator:
            args.append('--ignore-decorators=%s' % self.decorator)
        if self.deprecation_guard:
            args.append('--deprecated-guards=%s' % self.deprecation_guard)
        if self.output_dir:
            args.append('--output-dir=%s' % self.output_dir)

        # We only need to pass the list of ignored files if the we are not using an explicit list of headers.
        if not self.headers:
            # gtkdoc-scan wants the basenames of ignored headers, so strip the
            # dirname. Different from "--source-dir", the headers should be
            # specified as one long string.
            ignored_files_basenames = self._ignored_files_basenames()
            if ignored_files_basenames:
                args.append('--ignore-headers=%s' % ignored_files_basenames)

        if self.headers:
            args.extend(self.headers)

        self._run_command(args)

    def _run_gtkdoc_scangobj(self):
        env = os.environ
        ldflags = self.ldflags
        if self.library_path:
            additional_ldflags = ''
            for arg in env.get('LDFLAGS', '').split(' '):
                if arg.startswith('-L'):
                    additional_ldflags = '%s %s' % (additional_ldflags, arg)
            ldflags = ' "-L%s" %s ' % (self.library_path, additional_ldflags) + ldflags
            current_ld_library_path = env.get('LD_LIBRARY_PATH')
            if current_ld_library_path:
                env['RUN'] = 'LD_LIBRARY_PATH="%s:%s" ' % (self.library_path, current_ld_library_path)
            else:
                env['RUN'] = 'LD_LIBRARY_PATH="%s" ' % self.library_path

        if ldflags:
            env['LDFLAGS'] = '%s %s' % (ldflags, env.get('LDFLAGS', ''))
        if self.cflags:
            env['CFLAGS'] = '%s %s' % (self.cflags, env.get('CFLAGS', ''))

        if 'CFLAGS' in env:
            self.logger.debug('CFLAGS=%s', env['CFLAGS'])
        if 'LDFLAGS' in env:
            self.logger.debug('LDFLAGS %s', env['LDFLAGS'])
        if 'RUN' in env:
            self.logger.debug('RUN=%s', env['RUN'])
        self._run_command(['gtkdoc-scangobj', '--module=%s' % self.module_name],
                          env=env, cwd=self.output_dir)

    def _run_gtkdoc_mkdb(self):
        sgml_file = os.path.join(self.output_dir, self.main_sgml_file)
        self._raise_exception_if_file_inaccessible(sgml_file)

        args = ['gtkdoc-mkdb',
                '--module=%s' % self.module_name,
                '--main-sgml-file=%s' % sgml_file,
                '--source-suffixes=h,c,cpp,cc',
                '--output-format=xml',
                '--sgml-mode']

        if self.namespace:
            args.append('--name-space=%s' % self.namespace)

        ignored_files_basenames = self._ignored_files_basenames()
        if ignored_files_basenames:
            args.append('--ignore-files=%s' % ignored_files_basenames)

        # Each directory should be have its own "--source-dir=" prefix.
        args.extend(['--source-dir=%s' % path for path in self.source_dirs])
        self._run_command(args, cwd=self.output_dir)

    def _run_gtkdoc_mkhtml(self):
        html_dest_dir = os.path.join(self.output_dir, 'html')
        if not os.path.isdir(html_dest_dir):
            raise Exception("%s is not a directory, could not generate HTML"
                            % html_dest_dir)
        elif not os.access(html_dest_dir, os.X_OK | os.R_OK | os.W_OK):
            raise Exception("Could not access %s to generate HTML"
                            % html_dest_dir)

        # gtkdoc-mkhtml expects the SGML path to be absolute.
        sgml_file = os.path.join(os.path.abspath(self.output_dir),
                                 self.main_sgml_file)
        self._raise_exception_if_file_inaccessible(sgml_file)

        self._run_command(['gtkdoc-mkhtml', self.module_name, sgml_file],
                          cwd=html_dest_dir)

    def _run_gtkdoc_fixxref(self):
        args = ['gtkdoc-fixxref',
                '--module-dir=html',
                '--html-dir=html']
        args.extend(['--extra-dir=%s' % extra_dir for extra_dir in self.cross_reference_deps])
        self._run_command(args, cwd=self.output_dir, ignore_warnings=True)

    def rebase_installed_docs(self):
        if not os.path.isdir(self.output_dir):
            raise Exception("Tried to rebase documentation before generating it.")
        html_dir = os.path.join(self.virtual_root + self.prefix, 'share', 'gtk-doc', 'html', self.module_name)
        if not os.path.isdir(html_dir):
            return
        args = ['gtkdoc-rebase',
                '--relative',
                '--html-dir=%s' % html_dir]
        args.extend(['--other-dir=%s' % extra_dir for extra_dir in self.cross_reference_deps])
        if self.virtual_root:
            args.extend(['--dest-dir=%s' % self.virtual_root])
        self._run_command(args, cwd=self.output_dir)

    def api_missing_documentation(self):
        unused_doc_file = os.path.join(self.output_dir, self.module_name + "-unused.txt")
        if not os.path.exists(unused_doc_file) or not os.access(unused_doc_file, os.R_OK):
            return []
        return open(unused_doc_file).read().splitlines()

class PkgConfigGTKDoc(GTKDoc):

    """Class reads a library's pkgconfig file to guess gtkdoc parameters.

    Some gtkdoc parameters can be guessed by reading a library's pkgconfig
    file, including the cflags, ldflags and version parameters. If you
    provide these parameters as well, they will be appended to the ones
    guessed via the pkgconfig file.

    Keyword arguments:
      pkg_config_path -- Path to the pkgconfig file for the library. Required.
    """

    def __init__(self, pkg_config_path, args):
        super(PkgConfigGTKDoc, self).__init__(args)

        pkg_config = os.environ.get('PKG_CONFIG', 'pkg-config')

        if not os.path.exists(pkg_config_path):
            raise Exception('Could not find pkg-config file at: %s'
                            % pkg_config_path)

        self.cflags += " " + self._run_command([pkg_config,
                                                pkg_config_path,
                                                '--cflags'], print_output=False)
        self.ldflags += " " + self._run_command([pkg_config,
                                                pkg_config_path,
                                                '--libs'], print_output=False)
        self.version = self._run_command([pkg_config,
                                          pkg_config_path,
                                          '--modversion'], print_output=False)
        self.prefix = self._run_command([pkg_config,
                                         pkg_config_path,
                                         '--variable=prefix'], print_output=False)
