#!/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")
        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()
