#!/usr/bin/env python3
#
# Copyright (C) 2005 Holger Hans Peter Freyther
#
# SPDX-License-Identifier: GPL-2.0-only
#

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()
