# 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/.

import collections
import datetime
import logging

import blinker
import ipywidgets as widgets

from . import config
from . import deploymgr
from . import modelbrowser
from . import repomgr
from . import slicecfg
from . import listtable

from ..core.config import CFG

class StatusHistoryTable(listtable.ListTable):
  COLS = ["Time", "Level", "Message"]
  ROW = ["{time}", "{level}", "{message}"]
  def __init__ (self, data):
    super().__init__(StatusHistoryTable.COLS, StatusHistoryTable.ROW, data)


class TrafTabManager():
  def __init__ (self):
    self._status_log = collections.deque([], maxlen=25)

    self._buildStatus()
    self._buildTabs()

    self._w_vbox = widgets.VBox([self._w_tabs, self._w_vbox_status], layout = widgets.Layout(width="99%"))

  def display (self):
    return self._w_vbox

  def _buildStatus (self):
    # TODO: move status core to be loaded with extension and always logged
    self._w_status = widgets.Text(description = "", disabled = True,
                                  layout = widgets.Layout(width="99%"))
    self._signal_status = blinker.signal("status.update")
    self._signal_status.connect(self._updateStatus)
    self._w_button_expandstatus = widgets.Button(icon="align-justify", layout = widgets.Layout(width="50px"),
                                                 tooltip = "Show History")
    self._w_button_expandstatus.on_click(self._expandStatus)
    self._w_output_expandedstatus = widgets.Output()
    self._status_expanded = False

    self._w_hbox_status = widgets.HBox([self._w_status, self._w_button_expandstatus],
                                       layout = widgets.Layout(width="98%"))
    self._w_vbox_status = widgets.VBox([self._w_hbox_status], layout = widgets.Layout(width="auto"))

  def _buildTabs (self):
    #TODO: Defer costly initializations for tabs that are not visible

    # Repositories
    self._repomgr = repomgr.RepoManager()

    # Models
    self._modelbrowser = modelbrowser.ModelBrowser(self._repomgr)

    # Slice Binding
    self._slicecfg = slicecfg.SliceTgenConfigurator(self._repomgr)

    # Slice Timing

    # Deployment
    self._deploymgr = deploymgr.DeploymentManager(self)

    # Config
    self._configmgr = config.ConfigManager(self)

    tlist = [self._modelbrowser.display(), self._repomgr.display(), self._slicecfg.display(),
             self._deploymgr.display(), self._configmgr.display()]
    titles = ["Models", "Repositories", "Slice Binding", "Deploy", "Config"]
    self._w_tabs = widgets.Tab(layout = widgets.Layout(width="99%"), children=tlist, titles=titles)

  def _updateStatus (self, sender, level = logging.INFO, message = ""):
    if level >= CFG.get("log.ui-level"):
      nowstr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
      self._status_log.append({"time" : nowstr, "level" : level, "message" : message})
      self._w_status.value = "[%s] %s" % (nowstr, message)
      if self._status_expanded:
        self._w_output_expandedstatus.clear_output(wait=True)
        self._renderStatusLog()

  def _renderStatusLog (self):
    with self._w_output_expandedstatus:
      display(StatusHistoryTable(self._status_log))

#    self._w_output_expandedstatus.append_display_data(StatusHistoryTable(self._status_log))

  def _expandStatus (self, _):
    if self._status_expanded:
      self._w_output_expandedstatus.clear_output()
      self._w_vbox_status.children = [self._w_hbox_status]
      self._status_expanded = False
    else:
      self._renderStatusLog()
      self._w_vbox_status.children = [self._w_hbox_status, self._w_output_expandedstatus]
      self._status_expanded = True

