# Copyright (c) 2016 Comcast Cable Communications Management, LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Generation template class

import html.parser
import json
import logging
import os
import sys
import re

import jinja2

# Classes register themselves in this dictionary
"""Mapping of known processors to their classes"""
siphons = {}

"""Mapping of known output formats to their classes"""
formats = {}


class Siphon(object):
    """Generate rendered output for siphoned data."""

    # Set by subclasses
    """Our siphon name"""
    name = None

    # Set by subclasses
    """Name of an identifier used by this siphon"""
    identifier = None

    # Set by subclasses
    """The pyparsing object to use to parse with"""
    _parser = None

    """The input data"""
    _cmds = None

    """Group key to (directory,file) mapping"""
    _group = None

    """Logging handler"""
    log = None

    """Directory to look for siphon rendering templates"""
    template_directory = None

    """Directory to output parts in"""
    outdir = None

    """Template environment, if we're using templates"""
    _tplenv = None

    def __init__(self, template_directory, format, outdir, repository_link):
        super(Siphon, self).__init__()
        self.log = logging.getLogger("siphon.process.%s" % self.name)

        # Get our output format details
        fmt_klass = formats[format]
        fmt = fmt_klass()
        self._format = fmt

        # Sort out the template search path
        def _tpldir(name):
            return os.sep.join((template_directory, fmt.name, name))

        self.template_directory = template_directory
        searchpath = [
            _tpldir(self.name),
            _tpldir("default"),
        ]
        self.outdir = outdir
        loader = jinja2.FileSystemLoader(searchpath=searchpath)
        self._tplenv = jinja2.Environment(
            loader=loader,
            trim_blocks=True,
            autoescape=False,
            keep_trailing_newline=True)

        # Convenience, get a reference to the internal escape and
        # unescape methods in html.parser. These then become
        # available to templates to use, if needed.
        self._h = html.parser.HTMLParser()
        self.escape = html.escape
        self.unescape = html.unescape

        # TODO: customize release
        self.repository_link = repository_link

    # Output renderers

    """Returns an object to be used as the sorting key in the item index."""
    def index_sort_key(self, group):
        return group

    """Returns a string to use as the header at the top of the item index."""
    def index_header(self):
        return self.template("index_header")

    """Returns the string fragment to use for each section in the item
    index."""
    def index_section(self, group):
        return self.template("index_section", group=group)

    """Returns the string fragment to use for each entry in the item index."""
    def index_entry(self, meta, item):
        return self.template("index_entry", meta=meta, item=item)

    """Returns an object, typically a string, to be used as the sorting key
    for items within a section."""
    def item_sort_key(self, item):
        return item['name']

    """Returns a key for grouping items together."""
    def group_key(self, directory, file, macro, name):
        _global = self._cmds['_global']

        if file in _global and 'group_label' in _global[file]:
            self._group[file] = (directory, file)
            return file

        self._group[directory] = (directory, None)
        return directory

    """Returns a key for identifying items within a grouping."""
    def item_key(self, directory, file, macro, name):
        return name

    """Returns a string to use as the header when rendering the item."""
    def item_header(self, group):
        return self.template("item_header", group=group)

    """Returns a string to use as the body when rendering the item."""
    def item_format(self, meta, item):
        return self.template("item_format", meta=meta, item=item)

    """Returns a string to use as the label for the page reference."""
    def page_label(self, group):
        return "_".join((
            self.name,
            self.sanitize_label(group)
        ))

    """Returns a title to use for a page."""
    def page_title(self, group):
        _global = self._cmds['_global']
        (directory, file) = self._group[group]

        if file and file in _global and 'group_label' in _global[file]:
            return _global[file]['group_label']

        if directory in _global and 'group_label' in _global[directory]:
            return _global[directory]['group_label']

        return directory

    """Returns a string to use as the label for the section reference."""
    def item_label(self, group, item):
        return "__".join((
            self.name,
            item
        ))

    """Label sanitizer; for creating Doxygen references"""
    def sanitize_label(self, value):
        return value.replace(" ", "_") \
                    .replace("/", "_") \
                    .replace(".", "_")

    """Template processor"""
    def template(self, name, **kwargs):
        tpl = self._tplenv.get_template(name + self._format.extension)
        return tpl.render(
            this=self,
            **kwargs)

    # Processing methods

    """Parse the input file into a more usable dictionary structure."""
    def load_json(self, files):
        self._cmds = {}
        self._group = {}

        line_num = 0
        line_start = 0
        for filename in files:
            filename = os.path.relpath(filename)
            self.log.info("Parsing items in file \"%s\"." % filename)
            data = None
            with open(filename, "r") as fd:
                data = json.load(fd)

            self._cmds['_global'] = data['global']

            # iterate the items loaded and regroup it
            for item in data["items"]:
                try:
                    o = self._parser.parse(item['block'])
                except Exception:
                    self.log.error("Exception parsing item: %s\n%s"
                                   % (json.dumps(item, separators=(',', ': '),
                                                 indent=4),
                                      item['block']))
                    raise

                # Augment the item with metadata
                o["meta"] = {}
                for key in item:
                    if key == 'block':
                        continue
                    o['meta'][key] = item[key]

                # Load some interesting fields
                directory = item['directory']
                file = item['file']
                macro = o["macro"]
                name = o["name"]

                # Generate keys to group items by
                group_key = self.group_key(directory, file, macro, name)
                item_key = self.item_key(directory, file, macro, name)

                if group_key not in self._cmds:
                    self._cmds[group_key] = {}

                self._cmds[group_key][item_key] = o

    """Iterate over the input data, calling render methods to generate the
    output."""
    def process(self, out=None):

        if out is None:
            out = sys.stdout

        # Accumulated body contents
        contents = ""

        # Write the header for this siphon type
        out.write(self.index_header())

        # Sort key helper for the index
        def group_sort_key(group):
            return self.index_sort_key(group)

        # Iterate the dictionary and process it
        for group in sorted(self._cmds.keys(), key=group_sort_key):
            if group.startswith('_'):
                continue

            self.log.info("Processing items in group \"%s\" (%s)." %
                          (group, group_sort_key(group)))

            # Generate the section index entry (write it now)
            out.write(self.index_section(group))

            # Generate the item header (save for later)
            contents += self.item_header(group)

            def item_sort_key(key):
                return self.item_sort_key(self._cmds[group][key])

            for key in sorted(self._cmds[group].keys(), key=item_sort_key):
                self.log.debug("--- Processing key \"%s\" (%s)." %
                               (key, item_sort_key(key)))

                o = self._cmds[group][key]
                meta = {
                    "directory": o['meta']['directory'],
                    "file": o['meta']['file'],
                    "macro": o['macro'],
                    "name": o['name'],
                    "key": key,
                    "label": self.item_label(group, key),
                }

                # Generate the index entry for the item (write it now)
                out.write(self.index_entry(meta, o))

                # Generate the item itself (save for later)
                contents += self.item_format(meta, o)

            page_name = self.separate_page_names(group)
            if page_name != "":
                path = os.path.join(self.outdir, page_name)
                with open(path, "w+") as page:
                    page.write(contents)
                contents = ""

        # Deliver the accumulated body output
        out.write(contents)

    def do_cliexstart(self, matchobj):
        title = matchobj.group(1)
        title = ' '.join(title.splitlines())
        content = matchobj.group(2)
        content = re.sub(r"\n", r"\n    ", content)
        return "\n\n.. code-block:: console\n\n    %s\n    %s\n\n" % (title, content)

    def do_clistart(self, matchobj):
        content = matchobj.group(1)
        content = re.sub(r"\n", r"\n    ", content)
        return "\n\n.. code-block:: console\n\n    %s\n\n" % content

    def do_cliexcmd(self, matchobj):
        content = matchobj.group(1)
        content = ' '.join(content.splitlines())
        return "\n\n.. code-block:: console\n\n    %s\n\n" % content

    def process_list(self, matchobj):
        content = matchobj.group(1)
        content = self.reindent(content, 2)
        return "@@@@%s\nBBBB" % content

    def process_special(self, s):
        # ----------- markers to remove
        s = re.sub(r"@cliexpar\s*", r"", s)
        s = re.sub(r"@parblock\s*", r"", s)
        s = re.sub(r"@endparblock\s*", r"", s)
        s = re.sub(r"<br>", "", s)
        # ----------- emphasis
        # <b><em>
        s = re.sub(r"<b><em>\s*", "``", s)
        s = re.sub(r"\s*</b></em>", "``", s)
        s = re.sub(r"\s*</em></b>", "``", s)
        # <b>
        s = re.sub(r"<b>\s*", "**", s)
        s = re.sub(r"\s*</b>", "**", s)
        # <code>
        s = re.sub(r"<code>\s*", "``", s)
        s = re.sub(r"\s*</code>", "``", s)
        # <em>
        s = re.sub(r"'?<em>\s*", r"``", s)
        s = re.sub(r"\s*</em>'?", r"``", s)
        # @c <something>
        s = re.sub(r"@c\s(\S+)", r"``\1``", s)
        # ----------- todos
        s = re.sub(r"@todo[^\n]*", "", s)
        s = re.sub(r"@TODO[^\n]*", "", s)
        # ----------- code blocks
        s = re.sub(r"@cliexcmd{(.+?)}", self.do_cliexcmd, s, flags=re.DOTALL)
        s = re.sub(r"@cliexstart{(.+?)}(.+?)@cliexend", self.do_cliexstart, s, flags=re.DOTALL)
        s = re.sub(r"@clistart(.+?)@cliend", self.do_clistart, s, flags=re.DOTALL)
        # ----------- lists
        s = re.sub(r"^\s*-", r"\n@@@@", s, flags=re.MULTILINE)
        s = re.sub(r"@@@@(.*?)\n\n+", self.process_list, s, flags=re.DOTALL)
        s = re.sub(r"BBBB@@@@", r"-", s)
        s = re.sub(r"@@@@", r"-", s)
        s = re.sub(r"BBBB", r"\n\n", s)
        # ----------- Cleanup remains
        s = re.sub(r"@cliexend\s*", r"", s)
        return s

    def separate_page_names(self, group):
        return ""

    # This push the given textblock <indent> spaces right
    def reindent(self, s, indent):
        ind = " " * indent
        s = re.sub(r"\n", "\n" + ind, s)
        return s

    # This aligns the given textblock left (no indent)
    def noindent(self, s):
        s = re.sub(r"\n[ \f\v\t]*", "\n", s)
        return s

class Format(object):
    """Output format class"""

    """Name of this output format"""
    name = None

    """Expected file extension of templates that build this format"""
    extension = None


class FormatMarkdown(Format):
    """Markdown output format"""
    name = "markdown"
    extension = ".md"


# Register 'markdown'
formats["markdown"] = FormatMarkdown


class FormatItemlist(Format):
    """Itemlist output format"""
    name = "itemlist"
    extension = ".itemlist"


# Register 'itemlist'
formats["itemlist"] = FormatItemlist
