# Copyright (c) 2018-2023  University of Houston Networking Lab
# Copyright (c) 2024  Kent State University CAE-NetLab

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

class ListTable():
  def __init__ (self, cols, row_template, data):
    self._data = data
    self._columns = cols
    self._row_template = row_template
    self._hlrow_template = row_template
    self._col_template = "<th><center>%s</center></th>"
    self._title = None
    self._opt_monospace = False
    self._opt_fontsize = 90
    self._opt_rowcolors = False
    self._opt_makerows = False

    self.border = False
    self.border_style = "solid"
    self.border_color = "#dfdfdf"
    self.border_inpx = 1
    self.border_outpx = 1

    self.padding = 1

    self.highlight_row = None
    self.highlight_color = "#ffff99"

  @staticmethod
  def makeRow (fmtlist):
    cells = []
    for cell in fmtlist:
      if isinstance(cell, tuple):
        cells.append("<td style=\"%s\">%s</td>" % (cell[0], cell[1]))
      else:
        cells.append("<td>%s</td>" % (cell))

    row_tmpl = "<tr>%s</tr>" % ("".join(cells))
    hlrow_tmpl = "<tr style=\"background-color: {hlcolor}\">%s</tr>" % ("".join(cells))
    return row_tmpl, hlrow_tmpl

  def buildRow (self, rowdata, highlight=False):
    if isinstance(rowdata, (list, tuple)):
      return self._row_template.format(*rowdata)
    elif isinstance(rowdata, dict):
      if highlight:
        return self._hlrow_template.format(hlcolor=highlight, **rowdata)
      return self._row_template.format(**rowdata)
    elif isinstance(rowdata, str):
      return self._row_template.format(rowdata)

  def _repr_html_ (self):
    if isinstance(self._row_template, list):
      self._row_template, self._hlrow_template = ListTable.makeRow(self._row_template)

    trlist = []
    for idx,row in enumerate(self._data):
      if isinstance(self.highlight_row, int) and idx == self.highlight_row:
        trlist.append(self.buildRow(row, self.highlight_color))
      elif isinstance(self.highlight_row, dict) and isinstance(row, dict):
        # highlight_row is a filter, e.g. {"state" : "forwarding"}
        highlight = self.highlight_color
        for k,v in self.highlight_row.items():
          if not row[k].count(v):
            highlight = False
            break
        trlist.append(self.buildRow(row, highlight))
      else:
        trlist.append(self.buildRow(row))

    collist = []
    for column in self._columns:
      collist.append(self._col_template % (column))

    frag = ["<div>"]

    allstyles = []
    thtdstyle = []
    eventrstyle = []
    if self._opt_monospace:
      allstyles.append("font-family: monospace;")
      allstyles.append("font-size:%d%%;" % (self._opt_fontsize))
    elif self._opt_fontsize != 90:
      allstyles.append("font-size:%d%%;" % (self._opt_fontsize))

    if self.border:
      allstyles.append("border: %dpx %s;" % (self.border_outpx, self.border_style))
      allstyles.append("border-color: %s;" % (self.border_color))
      allstyles.append("border-collapse: collapse;")

    if self.padding:
      thtdstyle.append("padding: %dpx;" % (self.padding))
      thtdstyle.append("text-align: right;")

    if self._opt_rowcolors:
      eventrstyle.append("background-color: #E0E0E0;")

    frag.append("<style scoped>")
    if allstyles:
      frag.append("table, th, td {")
      frag.extend(allstyles)
      frag.append("}")
    if thtdstyle:
      frag.append("th, td {")
      frag.extend(thtdstyle)
      frag.append("}")
    if eventrstyle:
      frag.append("tr:nth-child(even) {")
      frag.extend(eventrstyle)
      frag.append("}")

    frag.append("</style>")
#      tbl.append("style='%s'" % (" ".join(styles)))

#    retl = ["<%s>" % (" ".join(tbl))]

    tbl = ["<table>"]
    if self._title:
      tbl.append("<caption><center><b><i>%s</i><b></center></caption>" % (self._title))
    if collist:
      tbl.append("<tr>%s</tr>" % ("".join(collist)))
    tbl.extend(trlist)
    tbl.append("</table>")

    frag.extend(tbl)
    frag.append("</div>")

    return "\n".join(frag)
