# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A super minimal module that allows rendering of readable text/html.

Usage should be relatively straightforward. You wrap things you want to write
out in some of the nice types defined here, and then pass the result to one of
render_text_pieces/render_html_pieces.

In HTML, the types should all nest nicely. In text, eh (nesting anything in
Bold is going to be pretty ugly, probably).

Lists and tuples may be used to group different renderable elements.

Example:

render_text_pieces([
  Bold("Daily to-do list:"),
  UnorderedList([
    "Write code",
    "Go get lunch",
    ["Fix ", Bold("some"), " of the bugs in the aforementioned code"],
    [
      "Do one of the following:",
      UnorderedList([
        "Nap",
        "Round 2 of lunch",
        ["Look at ", Link("https://google.com/?q=memes", "memes")],
      ]),
    ],
    "What a rough day; time to go home",
  ]),
])

Turns into

**Daily to-do list:**
  - Write code
  - Go get lunch
  - Fix **some** of the bugs in said code
  - Do one of the following:
    - Nap
    - Round 2 of lunch
    - Look at memes
  - What a rough day; time to go home

...And similarly in HTML, though with an actual link.

The rendering functions should never mutate your input.
"""

from __future__ import print_function

import collections
import html
import typing as t

Bold = collections.namedtuple('Bold', ['inner'])
LineBreak = collections.namedtuple('LineBreak', [])
Link = collections.namedtuple('Link', ['href', 'inner'])
UnorderedList = collections.namedtuple('UnorderedList', ['items'])
# Outputs different data depending on whether we're emitting text or HTML.
Switch = collections.namedtuple('Switch', ['text', 'html'])

line_break = LineBreak()

# Note that these build up their values in a funky way: they append to a list
# that ends up being fed to `''.join(into)`. This avoids quadratic string
# concatenation behavior. Probably doesn't matter, but I care.

# Pieces are really a recursive type:
# Union[
#   Bold,
#   LineBreak,
#   Link,
#   List[Piece],
#   Tuple[...Piece],
#   UnorderedList,
#   str,
# ]
#
# It doesn't seem possible to have recursive types, so just go with Any.
Piece = t.Any  # pylint: disable=invalid-name


def _render_text_pieces(piece: Piece, indent_level: int,
                        into: t.List[str]) -> None:
  """Helper for |render_text_pieces|. Accumulates strs into |into|."""
  if isinstance(piece, LineBreak):
    into.append('\n' + indent_level * ' ')
    return

  if isinstance(piece, str):
    into.append(piece)
    return

  if isinstance(piece, Bold):
    into.append('**')
    _render_text_pieces(piece.inner, indent_level, into)
    into.append('**')
    return

  if isinstance(piece, Link):
    # Don't even try; it's ugly more often than not.
    _render_text_pieces(piece.inner, indent_level, into)
    return

  if isinstance(piece, UnorderedList):
    for p in piece.items:
      _render_text_pieces([line_break, '- ', p], indent_level + 2, into)
    return

  if isinstance(piece, Switch):
    _render_text_pieces(piece.text, indent_level, into)
    return

  if isinstance(piece, (list, tuple)):
    for p in piece:
      _render_text_pieces(p, indent_level, into)
    return

  raise ValueError('Unknown piece type: %s' % type(piece))


def render_text_pieces(piece: Piece) -> str:
  """Renders the given Pieces into text."""
  into = []
  _render_text_pieces(piece, 0, into)
  return ''.join(into)


def _render_html_pieces(piece: Piece, into: t.List[str]) -> None:
  """Helper for |render_html_pieces|. Accumulates strs into |into|."""
  if piece is line_break:
    into.append('<br />\n')
    return

  if isinstance(piece, str):
    into.append(html.escape(piece))
    return

  if isinstance(piece, Bold):
    into.append('<b>')
    _render_html_pieces(piece.inner, into)
    into.append('</b>')
    return

  if isinstance(piece, Link):
    into.append('<a href="' + piece.href + '">')
    _render_html_pieces(piece.inner, into)
    into.append('</a>')
    return

  if isinstance(piece, UnorderedList):
    into.append('<ul>\n')
    for p in piece.items:
      into.append('<li>')
      _render_html_pieces(p, into)
      into.append('</li>\n')
    into.append('</ul>\n')
    return

  if isinstance(piece, Switch):
    _render_html_pieces(piece.html, into)
    return

  if isinstance(piece, (list, tuple)):
    for p in piece:
      _render_html_pieces(p, into)
    return

  raise ValueError('Unknown piece type: %s' % type(piece))


def render_html_pieces(piece: Piece) -> str:
  """Renders the given Pieces into HTML."""
  into = []
  _render_html_pieces(piece, into)
  return ''.join(into)
