# libgo - script to build library.gnome.org
# Copyright (C) 2007-2009  Frederic Peters
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301  USA

import logging
import os
import re
import shutil
import stat
import subprocess
import tempfile

from base import DocModule

class HtmlFilesModule(DocModule):
    '''Class for documentation shipped in a tarball as HTML files'''
    transform_mode = None
    index_filename = None
    tarball_doc_elem = None
    extra_xslt_attribs = None

    html2html_xsl_file = os.path.join(data_dir, 'xslt', 'html2html.xsl')

    related_xsl_files = ['html2html.xsl', 'heading.xsl']

    def create_from_tar(cls, tar, tarinfo, tarball_doc_elem):
        self = super(HtmlFilesModule, cls).create_from_tar(tar, tarinfo, None)
        self.tarball_doc_elem = tarball_doc_elem
        self.modulename = self.tarball_doc_elem.attrib.get('doc_module')
        if self.tarball_doc_elem.find('transform-mode') is not None:
            self.transform_mode = self.tarball_doc_elem.find('transform-mode').text
        if self.tarball_doc_elem.find('index') is not None:
            self.index_filename = self.tarball_doc_elem.find('index').text
        return self
    create_from_tar = classmethod(create_from_tar)

    def setup_channel(self):
        self.channel = self.tarball_doc_elem.attrib.get('channel')
 
    def __str__(self):
        return 'HTML files module at %s' % self.dirname

    def process(self):
        doc_module = self.modulename
        ext_dirname = os.path.join(app.config.private_dir, 'extracts')

        web_output_dir = app.get_module_web_output_dir(self)
        if not os.path.exists(web_output_dir):
            os.makedirs(web_output_dir)

        if not app.rebuild_all and os.path.exists(os.path.join(web_output_dir, 'index.html')):
            mtime = os.stat(os.path.join(web_output_dir, 'index.html'))[stat.ST_MTIME]
        else:
            mtime = 0

        if mtime > max(self.mtime_tarball, self.mtime_xslt_files):
            logging.debug('using already generated doc')
        else:
            logging.info('generating doc in %s' % web_output_dir[len(app.config.output_dir):])

            try:
                import html5lib
            except ImportError:
                html5lib = None

            if html5lib:
                # convert files to XML, then process them with xsltproc
                # to get library.gnome.org look

                logging.debug('transforming files shipped with tarball')
                parser = html5lib.HTMLParser()

                for filename in os.listdir(os.path.join(ext_dirname, self.dirname)):
                    src = os.path.join(ext_dirname, self.dirname, filename)
                    dst = os.path.join(web_output_dir, filename)
                    if not filename.endswith('.html'):
                        continue
                    doc = parser.parse(open(src))
                    doc.childNodes[-1].attributes['xmlns'] = 'http://www.w3.org/1999/xhtml'
                    temporary = tempfile.NamedTemporaryFile()
                    temporary.write(doc.childNodes[-1].toxml().encode('utf-8'))
                    temporary.flush()

                    cmd = ['xsltproc', '--output', dst,
                            '--nonet', '--xinclude',
                            self.html2html_xsl_file,
                            os.path.join(ext_dirname,
                                    self.dirname, temporary.name)]
                    if self.transform_mode:
                        cmd.insert(-2, '--stringparam')
                        cmd.insert(-2, 'libgo.h2hmode')
                        cmd.insert(-2, self.transform_mode)
                    if self.extra_xslt_attribs:
                        for k in self.extra_xslt_attribs:
                            cmd.insert(-2, '--stringparam')
                            cmd.insert(-2, 'libgo.%s' % k)
                            cmd.insert(-2, self.extra_xslt_attribs[k])

                    if app.config.symbols_dbm_filepath:
                        cmd.insert(-2, '--param')
                        cmd.insert(-2, 'libgo.dbm_support')
                        cmd.insert(-2, 'true()')

                    rc = subprocess.call(cmd)
            else:
                # simply copy HTML files shipped in tarball
                logging.debug('copying files shipped with tarball')
                for filename in os.listdir(os.path.join(ext_dirname, self.dirname)):
                    src = os.path.join(ext_dirname, self.dirname, filename)
                    dst = os.path.join(web_output_dir, filename)
                    if not filename.endswith('.html'):
                        continue
                    if not os.path.exists(dst) or \
                            os.stat(src)[stat.ST_MTIME] > os.stat(dst)[stat.ST_MTIME]:
                        open(dst, 'w').write(open(src, 'r').read())

            # copy non-html files
            for filename in os.listdir(os.path.join(ext_dirname, self.dirname)):
                src = os.path.join(ext_dirname, self.dirname, filename)
                dst = os.path.join(web_output_dir, filename)
                if filename.endswith('.html'):
                    continue
                if os.path.isdir(src):
                    if os.path.exists(dst):
                        shutil.rmtree(dst)
                    shutil.copytree(src, dst)
                else:
                    if not os.path.exists(dst) or \
                            os.stat(src)[stat.ST_MTIME] > os.stat(dst)[stat.ST_MTIME]:
                        open(dst, 'w').write(open(src, 'r').read())

        doc = self.get_libgo_document(['en'])
        if not doc:
            return

        if self.tarball_doc_elem:
            doc.category = self.tarball_doc_elem.get('category')
            doc.toc_id = doc.category

        if self.index_filename:
            path = os.path.join(web_output_dir, 'index.html')
            if os.path.exists(path):
                os.unlink(path)
            try:
                os.symlink(self.index_filename, path)
            except OSError:
                return

        if not os.path.exists(os.path.join(web_output_dir, 'index.html')):
            return

        title = re.findall('<title>(.*)</title>',
                file(os.path.join(web_output_dir, 'index.html')).read())
        if title:
            doc.title = {'en': title[0]}

        self.install_version_symlinks(doc)

