#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2005 Holger Hans Peter Freyther
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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 optparse, os, sys

# bitbake
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__), 'lib'))
import bb
import bb.parse
from   string import split, join

__version__ = "0.0.2"

class HTMLFormatter:
    """
    Simple class to help to generate some sort of HTML files. It is
    quite inferior solution compared to docbook, gtkdoc, doxygen but it
    should work for now.
    We've a global introduction site (index.html) and then one site for
    the list of keys (alphabetical sorted) and one for the list of groups,
    one site for each key with links to the relations and groups.

        index.html
        all_keys.html
        all_groups.html
        groupNAME.html
        keyNAME.html
    """

    def replace(self, text, *pairs):
        """
        From pydoc... almost identical at least
        """
        while pairs:
            (a, b) = pairs[0]
            text = join(split(text, a), b)
            pairs = pairs[1:]
        return text
    def escape(self, text):
        """
        Escape string to be conform HTML
        """
        return self.replace(text, 
                            ('&', '&amp;'), 
                            ('<', '&lt;' ),
                            ('>', '&gt;' ) )
    def createNavigator(self):
        """
        Create the navgiator
        """
        return """<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
<tr valign="middle">
<td><a accesskey="g" href="index.html">Home</a></td>
<td><a accesskey="n" href="all_groups.html">Groups</a></td>
<td><a accesskey="u" href="all_keys.html">Keys</a></td>
</tr></table>
"""

    def relatedKeys(self, item):
        """
        Create HTML to link to foreign keys
        """

        if len(item.related()) == 0:
            return ""

        txt = "<p><b>See also:</b><br>"
        txts = []
        for it in item.related():
            txts.append("""<a href="key%(it)s.html">%(it)s</a>""" % vars() )

        return txt + ",".join(txts)

    def groups(self, item):
        """
        Create HTML to link to related groups
        """

        if len(item.groups()) == 0:
            return ""


        txt = "<p><b>See also:</b><br>"
        txts = []
        for group in item.groups():
            txts.append( """<a href="group%s.html">%s</a> """ % (group, group) )

        return txt + ",".join(txts)


    def createKeySite(self, item):
        """
        Create a site for a key. It contains the header/navigator, a heading,
        the description, links to related keys and to the groups.
        """

        return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Key %s</title></head>
<link rel="stylesheet" href="style.css" type="text/css">
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
%s
<h2><span class="refentrytitle">%s</span></h2>

<div class="refsynopsisdiv">
<h2>Synopsis</h2>
<p>
%s
</p>
</div>

<div class="refsynopsisdiv">
<h2>Related Keys</h2>
<p>
%s
</p>
</div>

<div class="refsynopsisdiv">
<h2>Groups</h2>
<p>
%s
</p>
</div>


</body>
"""     % (item.name(), self.createNavigator(), item.name(), 
           self.escape(item.description()), self.relatedKeys(item), self.groups(item))

    def createGroupsSite(self, doc):
        """
        Create the Group Overview site
        """

        groups = ""
        sorted_groups = sorted(doc.groups())
        for group in sorted_groups:
            groups += """<a href="group%s.html">%s</a><br>""" % (group, group)

        return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Group overview</title></head>
<link rel="stylesheet" href="style.css" type="text/css">
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
%s
<h2>Available Groups</h2>
%s
</body>
""" % (self.createNavigator(), groups)

    def createIndex(self):
        """
        Create the index file
        """

        return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Bitbake Documentation</title></head>
<link rel="stylesheet" href="style.css" type="text/css">
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
%s
<h2>Documentation Entrance</h2>
<a href="all_groups.html">All available groups</a><br>
<a href="all_keys.html">All available keys</a><br>
</body>
""" % self.createNavigator()

    def createKeysSite(self, doc):
        """
        Create Overview of all avilable keys
        """
        keys = ""
        sorted_keys = sorted(doc.doc_keys())
        for key in sorted_keys:
            keys += """<a href="key%s.html">%s</a><br>""" % (key, key)

        return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Key overview</title></head>
<link rel="stylesheet" href="style.css" type="text/css">
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
%s
<h2>Available Keys</h2>
%s
</body>
""" % (self.createNavigator(), keys)

    def createGroupSite(self, gr, items, _description = None):
        """
        Create a site for a group:
        Group the name of the group, items contain the name of the keys
        inside this group
        """
        groups = ""
        description = ""

        # create a section with the group descriptions
        if _description:
            description  += "<h2 Description of Grozp %s</h2>" % gr
            description  += _description

        items.sort(lambda x, y:cmp(x.name(), y.name()))
        for group in items:
            groups += """<a href="key%s.html">%s</a><br>""" % (group.name(), group.name())

        return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Group %s</title></head>
<link rel="stylesheet" href="style.css" type="text/css">
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
%s
%s
<div class="refsynopsisdiv">
<h2>Keys in Group %s</h2>
<pre class="synopsis">
%s
</pre>
</div>
</body>
""" % (gr, self.createNavigator(), description, gr, groups)



    def createCSS(self):
        """
        Create the CSS file
        """
        return """.synopsis, .classsynopsis
{
  background: #eeeeee;
  border: solid 1px #aaaaaa;
  padding: 0.5em;
}
.programlisting
{
  background: #eeeeff;
  border: solid 1px #aaaaff;
  padding: 0.5em;
}
.variablelist
{
  padding: 4px;
  margin-left: 3em;
}
.variablelist td:first-child
{
  vertical-align: top;
}
table.navigation
{
  background: #ffeeee;
  border: solid 1px #ffaaaa;
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}
.navigation a
{
  color: #770000;
}
.navigation a:visited
{
  color: #550000;
}
.navigation .title
{
  font-size: 200%;
}
div.refnamediv
{
  margin-top: 2em;
}
div.gallery-float
{
  float: left;
  padding: 10px;
}
div.gallery-float img
{
  border-style: none;
}
div.gallery-spacer
{
  clear: both;
}
a
{
  text-decoration: none;
}
a:hover
{
  text-decoration: underline;
  color: #FF0000;
}
"""



class DocumentationItem:
    """
    A class to hold information about a configuration
    item. It contains the key name, description, a list of related names,
    and the group this item is contained in.
    """

    def __init__(self):
        self._groups  = []
        self._related = []
        self._name    = ""
        self._desc    = ""

    def groups(self):
        return self._groups

    def name(self):
        return self._name

    def description(self):
        return self._desc

    def related(self):
        return self._related

    def setName(self, name):
        self._name = name

    def setDescription(self, desc):
        self._desc = desc

    def addGroup(self, group):
        self._groups.append(group)

    def addRelation(self, relation):
        self._related.append(relation)

    def sort(self):
        self._related.sort()
        self._groups.sort()


class Documentation:
    """
    Holds the documentation... with mappings from key to items...
    """

    def __init__(self):
        self.__keys   = {}
        self.__groups = {}

    def insert_doc_item(self, item):
        """
        Insert the Doc Item into the internal list
        of representation
        """
        item.sort()
        self.__keys[item.name()] = item

        for group in item.groups():
            if not group in self.__groups:
                self.__groups[group] = []
            self.__groups[group].append(item)
            self.__groups[group].sort()


    def doc_item(self, key):
        """
        Return the DocumentationInstance describing the key
        """
        try:
            return self.__keys[key]
        except KeyError:
            return None

    def doc_keys(self):
        """
        Return the documented KEYS (names)
        """
        return self.__keys.keys()

    def groups(self):
        """
        Return the names of available groups
        """
        return self.__groups.keys()

    def group_content(self, group_name):
        """
        Return a list of keys/names that are in a specefic
        group or the empty list
        """
        try:
            return self.__groups[group_name]
        except KeyError:
            return []


def parse_cmdline(args):
    """
    Parse the CMD line and return the result as a n-tuple
    """

    parser = optparse.OptionParser( version = "Bitbake Documentation Tool Core version %s, %%prog version %s" % (bb.__version__, __version__))
    usage  = """%prog [options]

Create a set of html pages (documentation) for a bitbake.conf....
"""

    # Add the needed options
    parser.add_option( "-c", "--config", help = "Use the specified configuration file as source",
                       action = "store", dest = "config", default = os.path.join("conf", "documentation.conf") )

    parser.add_option( "-o", "--output", help = "Output directory for html files",
                       action = "store", dest = "output", default = "html/" )

    parser.add_option( "-D",  "--debug", help = "Increase the debug level",
                       action = "count", dest = "debug", default = 0 )

    parser.add_option( "-v", "--verbose", help = "output more chit-char to the terminal",
                       action = "store_true", dest = "verbose", default = False )

    options, args = parser.parse_args( sys.argv )
 
    bb.msg.init_msgconfig(options.verbose, options.debug)

    return options.config, options.output

def main():
    """
    The main Method
    """

    (config_file, output_dir) = parse_cmdline( sys.argv )

    # right to let us load the file now
    try:
        documentation = bb.parse.handle( config_file, bb.data.init() )
    except IOError:
        bb.fatal( "Unable to open %s" % config_file )
    except bb.parse.ParseError:
        bb.fatal( "Unable to parse %s" % config_file )

    if isinstance(documentation, dict):
        documentation = documentation[""]

    # Assuming we've the file loaded now, we will initialize the 'tree'
    doc = Documentation()

    # defined states
    state_begin = 0
    state_see   = 1
    state_group = 2

    for key in bb.data.keys(documentation):
        data   = documentation.getVarFlag(key, "doc", False)
        if not data:
            continue

        # The Documentation now starts
        doc_ins = DocumentationItem()
        doc_ins.setName(key)


        tokens = data.split(' ')
        state = state_begin
        string= ""
        for token in tokens:
            token = token.strip(',')

            if not state == state_see and token == "@see":
                state = state_see
                continue
            elif not state == state_group and token  == "@group":
                state = state_group
                continue

            if state == state_begin:
                string += " %s" % token
            elif state == state_see:
                doc_ins.addRelation(token)
            elif state == state_group:
                doc_ins.addGroup(token)

        # set the description
        doc_ins.setDescription(string)
        doc.insert_doc_item(doc_ins)

    # let us create the HTML now
    bb.utils.mkdirhier(output_dir)
    os.chdir(output_dir)

    # Let us create the sites now. We do it in the following order
    # Start with the index.html. It will point to sites explaining all
    # keys and groups
    html_slave = HTMLFormatter()

    f = file('style.css', 'w')
    print >> f, html_slave.createCSS()

    f = file('index.html', 'w')
    print >> f, html_slave.createIndex()

    f = file('all_groups.html', 'w')
    print >> f, html_slave.createGroupsSite(doc)

    f = file('all_keys.html', 'w')
    print >> f, html_slave.createKeysSite(doc)

    # now for each group create the site
    for group in doc.groups():
        f = file('group%s.html' % group, 'w')
        print >> f, html_slave.createGroupSite(group, doc.group_content(group))

    # now for the keys
    for key in doc.doc_keys():
        f = file('key%s.html' % doc.doc_item(key).name(), 'w')
        print >> f, html_slave.createKeySite(doc.doc_item(key))


if __name__ == "__main__":
    main()
