#!/usr/bin/env python

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

import datetime
import sys
import traceback

import common
import text

"""
Given a map of all connections with lists of the associated frames
analyze and show per-connection, per-session, and per-link details.

This is done in a two-step process: 
 * Run through the frame lists and generates an intermediate structure 
   with the the details for display.
 * Generate the html from the detail structure.
This strategy allows for a third step that would allow more details
to be gleaned from the static details. For instance, if router A
sends a transfer to router B then router A's details could show 
how long it took for the transfer to reach router B. Similarly
router B's details could show how long ago router A sent the transfer. 
"""

class Counts():
    """
    Holds common count sets that can be rolled up from links to
    sessions to connections. Not for individual performatives.
    """
    def __init__(self):
        # amqp errors gleaned from any performative
        self.errors = 0    # amqp error - simple count
        # derived facts about message settlement
        self.unsettled = 0
        self.presettled = 0
        self.accepted = 0
        self.rejected = 0
        self.released = 0
        self.modified = 0
        # interesting transfers
        self.aborted = 0
        self.more = 0
        self.incomplete = 0
        # link drained
        self.drain = 0
        # link out of credit
        self.credit_not_evaluated = 0
        self.no_credit = 0 # event count, excludes drain credit exhaustion
        self.initial_no_credit_duration = datetime.timedelta() # before first credit
        self.no_credit_duration = datetime.timedelta() # after credit issued and then exhausted

    def highlight(self, name, value, color):
        """
        if value is non zero then return a colorized 'name: value' text stream
        else return a blank string
        """
        result = ""
        if value:
            result = "<span style=\"background-color:%s\">%s: %s</span> " % (color, name, str(value))
        return result

    def highlight_duration(self, name, value, color):
        """
        if value is non zero then return a colorized 'name: value' text stream
        else return a blank string
        """
        result = ""
        if value.seconds > 0 or value.microseconds > 0:
            t = float(value.seconds) + float(value.microseconds) / 1000000.0
            result = "<span style=\"background-color:%s\">%s: %0.06f</span> " % (color, name, t)
        return result

    def show_html(self):
        res = ""
        res += self.highlight("errors", self.errors, common.color_of("errors"))
        res += self.highlight("unsettled", self.unsettled, common.color_of("unsettled"))
        res += self.highlight("presettled", self.presettled, common.color_of("presettled"))
        res += self.highlight("accepted", self.accepted, common.color_of("accepted"))
        res += self.highlight("rejected", self.rejected, common.color_of("rejected"))
        res += self.highlight("released", self.released, common.color_of("released"))
        res += self.highlight("modified", self.modified, common.color_of("modified"))
        res += self.highlight("aborted", self.aborted, common.color_of("aborted"))
        res += self.highlight("more", self.more, common.color_of("more"))
        res += self.highlight("incomplete", self.incomplete, common.color_of("unsettled"))
        res += self.highlight("drain", self.drain, common.color_of("drain"))
        res += self.highlight_duration("initial", self.initial_no_credit_duration, common.color_of("no_credit"))
        res += self.highlight("no_credit", self.no_credit, common.color_of("no_credit"))
        res += self.highlight_duration("duration", self.no_credit_duration, common.color_of("no_credit"))
        res += self.highlight("no_eval", self.credit_not_evaluated, common.color_of("no_credit"))
        return res

    @classmethod
    def show_table_heads1(cls):
        return "<th rowspan=\"2\"><span title=\"AMQP errors\">ERR</span></th>" \
               "<th colspan=\"6\">Settlement - disposition</th>" \
               "<th colspan=\"3\">Transfer</th>" \
               "<th>Flow</th>" \
               "<th colspan=\"4\">Credit starvation</th>"

    @classmethod
    def show_table_heads2(cls):
        return "<th><span title=\"Unsettled transfers\">UNSTL</span></th>" \
               "<th><span title=\"Presettled transfers\">PRE</span></th>" \
               "<th><span title=\"Disposition: accepted\">ACCPT</span></th>" \
               "<th><span title=\"Disposition: rejected\">RJCT</span></th>" \
               "<th><span title=\"Disposition: released\">RLSD</span></th>" \
               "<th><span title=\"Disposition: modified\">MDFD</span></th>" \
               "<th><span title=\"Transfer abort=true\">ABRT</span></th>" \
               "<th><span title=\"Transfer: more=true\">MOR</span></th>" \
               "<th><span title=\"Transfer: incomplete; all frames had more=true\">INC</span></th>" \
               "<th><span title=\"Flow: drain=true\">DRN</span></th>" \
               "<th><span title=\"Initial stall (S)\">initial (S)</span></th>" \
               "<th><span title=\"Credit exhausted\">-> 0</span></th>" \
               "<th><span title=\"Normal credit exhaustion stall (S)\">duration (S)</span></th>" \
               "<th><span title=\"Credit not evaluated\">?</span></th>"


    def show_table_element(self, name, value, color):
        return ("<td>%s</td>" % text.nbsp()) if value == 0 else \
            ("<td>%s</td>" % ("<span style=\"background-color:%s\">%s</span> " % (color, str(value))))

    def show_table_duration(self, delta):
        if delta.seconds == 0 and delta.microseconds == 0:
            return "<td>%s</td>" % text.nbsp()
        t = float(delta.seconds) + float(delta.microseconds) / 1000000.0
        return ("<td>%0.06f</td>" % t)

    def show_table_data(self):
        res = ""
        res += self.show_table_element("errors", self.errors, common.color_of("errors"))
        res += self.show_table_element("unsettled", self.unsettled, common.color_of("unsettled"))
        res += self.show_table_element("presettled", self.presettled, common.color_of("presettled"))
        res += self.show_table_element("accepted", self.accepted, common.color_of("accepted"))
        res += self.show_table_element("rejected", self.rejected, common.color_of("rejected"))
        res += self.show_table_element("released", self.released, common.color_of("released"))
        res += self.show_table_element("modified", self.modified, common.color_of("modified"))
        res += self.show_table_element("aborted", self.aborted, common.color_of("aborted"))
        res += self.show_table_element("more", self.more, common.color_of("more"))
        res += self.show_table_element("incomplete", self.incomplete, common.color_of("unsettled"))
        res += self.show_table_element("drain", self.drain, common.color_of("drain"))
        res += self.show_table_duration(self.initial_no_credit_duration)
        res += self.show_table_element("no_credit", self.no_credit, common.color_of("no_credit"))
        res += self.show_table_duration(self.no_credit_duration)
        res += self.show_table_element("?", self.credit_not_evaluated, common.color_of("no_credit"))
        return res



class ConnectionDetail():
    """
    Holds facts about sessions over the connection's lifetime
    """

    def __init__(self, id, router, conn):
        # id in form 'A_15':
        #   A is the router logfile key
        #   15 is the log connection number [15]
        self.id = id
        self.router = router
        self.conn = conn     # from router.conn_list

        # seq_no number differentiates items that otherwise have same identifiers.
        # Sessions, for example: a given connection may have N distinct session
        # with local channel 0.
        self.seq_no = 0

        # combined counts
        self.counts = Counts()

        # session_list holds all SessionDetail records either active or retired
        # Sessions for a connection are identified by the local channel number.
        # There may be many sessions all using the same channel number.
        # This list holds all of them.
        self.session_list = []

        # this map indexed by the channel refers to the current item in the session_list
        self.chan_map = {}

        # count of AMQP performatives for this connection that are not accounted
        # properly in session and link processing.
        # Server Accepting, SASL mechs, init, outcome, AMQP, and so on
        self.unaccounted_frame_list = []

    def FindSession(self, channel):
        """
        Find the current session by channel number
        :param channel: the performative channel
        :return: the session or None
        """
        return self.chan_map[channel] if channel in self.chan_map else None

    def GetId(self):
        return self.id

    def GetSeqNo(self):
        self.seq_no += 1
        return str(self.seq_no)

    def EndChannel(self, channel):
        # take existing session out of connection chan map
        if channel in self.chan_map:
            del self.chan_map[channel]

    def GetLinkEventCount(self):
        c = 0
        for session in self.session_list:
            c += session.GetLinkEventCount()
        return c


class SessionDetail:
    """
    Holds facts about a session
    """

    def __init__(self, id, conn_detail, conn_seq, start_time):
        # parent connection
        self.id = id
        self.conn_detail = conn_detail

        # some seq number
        self.conn_epoch = conn_seq

        # Timing
        self.time_start = start_time
        self.time_end = start_time

        # combined counts
        self.counts = Counts()

        self.channel = -1
        self.peer_chan = -1

        self.half_closed = False

        self.direction = ""

        # seq_no number differentiates items that otherwise have same identifiers.
        # links for example
        self.seq_no = 0

        self.log_line_list = []

        # link_list holds LinkDetail records
        # Links for a session are identified by a (handle, remote-handle) number pair.
        # There may be many links all using the same handle pairs.
        # This list holds all of them.
        self.link_list = []

        # link_list holds all links either active or retired
        # this map indexed by the handle refers to the current item in the link_list
        self.input_handle_link_map = {}  # link created by peer
        self.output_handle_link_map = {}  # link created locally

        # Link name in attach finds link details in link_list
        # This map contains the link handle to disambiguate the name
        self.link_name_to_detail_map = {}
        #
        # The map contains the pure link name and is used only to resolve name collisions
        self.link_name_conflict_map = {}

        # count of AMQP performatives for this connection that are not accounted
        # properly in link processing
        self.session_frame_list = []

        # Session dispositions
        # Sender/receiver dispositions may be sent or received
        self.rx_rcvr_disposition_map = {}  # key=delivery id, val=disposition plf
        self.rx_sndr_disposition_map = {}  # key=delivery id, val=disposition plf
        self.tx_rcvr_disposition_map = {}  # key=delivery id, val=disposition plf
        self.tx_sndr_disposition_map = {}  # key=delivery id, val=disposition plf

    def FrameCount(self):
        count = 0
        for link in self.link_list:
            count += len(link.frame_list)
        count += len(self.session_frame_list)
        return count

    def FindLinkByName(self, attach_name, link_name_unambiguous, parsed_log_line):
        # find conflicted name
        cnl = None
        if attach_name in self.link_name_conflict_map:
            cnl = self.link_name_conflict_map[attach_name]
            if cnl.input_handle == -1 and cnl.output_handle == -1:
                cnl = None
        # find non-conflicted name
        nl = None
        if link_name_unambiguous in self.link_name_to_detail_map:
            nl = self.link_name_to_detail_map[link_name_unambiguous]
            if nl.input_handle == -1 and nl.output_handle == -1:
                nl = None
        # report conflict
        # TODO: There's an issue with this logic generating false positives
        # if nl is None and (not cnl is None):
        #     parsed_log_line.data.amqp_error = True
        #     parsed_log_line.data.web_show_str += " <span style=\"background-color:yellow\">Link name conflict</span>"
        # return unambiguous link
        return nl

    def FindLinkByHandle(self, handle, find_remote):
        """
        Find the current link by handle number
        qualify lookup based on packet direction
        :param link: the performative channel
        :param dst_is_broker: packet direction
        :return: the session or None
        """
        if find_remote:
            return self.input_handle_link_map[handle] if handle in self.input_handle_link_map else None
        else:
            return self.output_handle_link_map[handle] if handle in self.output_handle_link_map else None

    def GetId(self):
        return self.conn_detail.GetId() + "_" + str(self.conn_epoch)

    def GetSeqNo(self):
        self.seq_no += 1
        return self.seq_no

    def DetachOutputHandle(self, handle):
        # take existing link out of session handle map
        if handle in self.output_handle_link_map:
            nl = self.output_handle_link_map[handle]
            del self.output_handle_link_map[handle]
            nl.output_handle = -1

    def DetachInputHandle(self, handle):
        # take existing link out of session remote handle map
        if handle in self.input_handle_link_map:
            nl = self.input_handle_link_map[handle]
            del self.input_handle_link_map[handle]
            nl.input_handle = -1

    def DetachHandle(self, handle, is_remote):
        if is_remote:
            self.DetachInputHandle(handle)
        else:
            self.DetachOutputHandle(handle)

    def GetLinkEventCount(self):
        c = 0
        for link in self.link_list:
            c += link.GetLinkEventCount()
        return c


class LinkDetail():
    """
    Holds facts about a link endpoint
    This structure binds input and output links with same name
    """

    def __init__(self, id, session_detail, session_seq, link_name, start_time):
        self.id = id
        # parent session
        self.session_detail = session_detail

        # some seq number
        self.session_seq = session_seq

        # link name
        self.name = link_name  # plf.data.link_short_name
        self.display_name = link_name  # show short name; hover to see long name

        # Timing
        self.time_start = start_time
        self.time_end = start_time

        # combined counts
        self.counts = Counts()

        self.unsettled_list = []


        # paired handles
        self.output_handle = -1
        self.input_handle = -1

        # link originator
        self.direction = ""
        self.is_receiver = True
        self.first_address = ''

        # set by sender
        self.snd_settle_mode = ''
        self.sender_target_address = "none"
        self.sender_class = ''

        # set by receiver
        self.rcv_settle_mode = ''
        self.receiver_source_address = "none"
        self.receiver_class = ''

        self.frame_list = []

    def GetId(self):
        return self.session_detail.GetId() + "_" + str(self.session_seq)

    def FrameCount(self):
        return len(self.frame_list)


class AllDetails():
    #
    #
    def format_errors(self, n_errors):
        return ("<span style=\"background-color:%s\">errors: %d</span>" % (common.color_of("errors"), n_errors)) if n_errors > 0 else ""

    def format_unsettled(self, n_unsettled):
        return ("<span style=\"background-color:%s\">unsettled: %d</span>" % (common.color_of("unsettled"), n_unsettled)) if n_unsettled > 0 else ""

    def classify_connection(self, id):
        """
        Return probable connection class based on the kinds of links the connection uses.
        TODO: This assumes that the connection has one session and one
        :param id:
        :return:
        """
        return "oops"

    def time_offset(self, ttest, t0):
        """
        Return a string time delta between two datetime objects in seconds formatted
        to six significant decimal places.
        :param ttest:
        :param t0:
        :return:
        """
        delta = ttest - t0
        t = float(delta.seconds) + float(delta.microseconds) / 1000000.0
        return "%0.06f" % t

    def links_in_connection(self, id):
        conn_details = self.conn_details[id]
        n_links = 0
        for sess in conn_details.session_list:
            n_links += len(sess.link_list)
        return n_links

    def settlement_display(self, transfer, disposition):
        """
        Generate the details for a disposition settlement
        :param transfer: plf
        :param disposition: plf
        :return: display string
        """
        state = disposition.data.disposition_state  # accept, reject, release, ...
        if state != "accepted":
            state = "<span style=\"background-color:orange\">%s</span>" % state
        l2disp = "<a href=\"#%s\">%s</a>" % (disposition.fid, state)
        sttld = "settled" if disposition.data.settled == "true" else "unsettled"
        delay = self.time_offset(disposition.datetime, transfer.datetime)
        return "(%s %s %s S)" % (l2disp, sttld, delay)

    def resolve_settlement(self, link, transfer, rcv_disposition, snd_disposition):
        """
        Generate the settlement display string for this transfer.
        :param link: linkDetails - holds settlement modes
        :param transfer: plf of the transfer frame
        :param rcv_disposition: plf of receiver role disposition
        :param snd_disposition: plf of sender   role disposition
        :return: display string
        """
        if transfer.data.settled is not None and transfer.data.settled == "true":
            result = "transfer presettled"
            transfer.data.transfer_presettled = True
            if rcv_disposition is not None:
                sys.stderr.write("WARING: Receiver disposition for presettled message. connid:%s, line:%s\n" %
                                 (rcv_disposition.data.conn_id, rcv_disposition.lineno))
            if snd_disposition is not None:
                sys.stderr.write("WARING: Sender disposition for presettled message. connid:%s, line:%s\n" %
                                 (snd_disposition.data.conn_id, snd_disposition.lineno))
        else:
            if "1" in link.snd_settle_mode:
                # link mode sends only settled transfers
                result = "link presettled"
                transfer.data.transfer_presettled = True
                if rcv_disposition is not None:
                    sys.stderr.write("WARING: Receiver disposition for presettled link. connid:%s, line:%s\n" %
                                     (rcv_disposition.data.conn_id, rcv_disposition.lineno))
                if snd_disposition is not None:
                    sys.stderr.write("WARING: Sender disposition for presettled link. connid:%s, line:%s\n" %
                                     (snd_disposition.data.conn_id, snd_disposition.lineno))
            else:
                # transfer unsettled and link mode requires settlement
                if rcv_disposition is not None:
                    rtext = self.settlement_display(transfer, rcv_disposition)
                    transfer.data.final_disposition = rcv_disposition
                if snd_disposition is not None:
                    stext = self.settlement_display(transfer, snd_disposition)
                    transfer.data.final_disposition = snd_disposition

                if "0" in link.rcv_settle_mode:
                    # one settlement expected
                    if rcv_disposition is not None:
                        result = rtext
                        if snd_disposition is not None:
                            sys.stderr.write("WARING: Sender disposition for single first(0) settlement link. "
                                             "connid:%s, line:%s\n" %
                                             (snd_disposition.data.conn_id, snd_disposition.lineno))
                    else:
                        if transfer.data.transfer_more:
                            result = "(pending)"
                        else:
                            result = "<span style=\"background-color:orange\">%s</span>" % "receive settlement absent"
                else:
                    # two settlements expected
                    if transfer.data.transfer_more:
                        result = "(pending)"
                    elif rcv_disposition is not None:
                        result = "receiver: " + rtext
                        if snd_disposition is not None:
                            result += ", sender: " + stext
                        else:
                            result += "<span style=\"background-color:orange\">%s</span>" % ", sender settlement absent"
                    else:
                        result = "<span style=\"background-color:orange\">%s</span>" % "receiver settlement absent"
                        if snd_disposition is not None:
                            result += ", sender: " + stext
                        else:
                            result += "<span style=\"background-color:orange\">%s</span>" % ", sender settlement absent"
        return result

    def __init__(self, _router, _common):
        self.rtr = _router
        self.comn = _common

        # conn_details - AMQP analysis
        #   key= connection id '1', '2'
        #   val= ConnectionDetails
        # for each connection, for each session, for each link:
        #   what happened
        self.conn_details = {}

        for conn in self.rtr.conn_list:
            id = self.rtr.conn_id(conn)
            self.conn_details[id] = ConnectionDetail(id, self.rtr, conn)
            conn_details = self.conn_details[id]
            conn_frames = self.rtr.conn_to_frame_map[id]
            for plf in conn_frames:
                pname = plf.data.name
                if plf.data.amqp_error:
                    conn_details.counts.errors += 1
                if pname in ['', 'open', 'close']:
                    conn_details.unaccounted_frame_list.append(plf)
                    continue
                # session required
                channel = plf.data.channel # Assume in/out channels are the same for the time being
                sess_details = conn_details.FindSession(channel)
                if sess_details == None:
                    new_id = len(conn_details.session_list)
                    sess_details = SessionDetail(new_id, conn_details, conn_details.GetSeqNo(), plf.datetime)
                    conn_details.session_list.append(sess_details)
                    conn_details.EndChannel(channel)
                    conn_details.chan_map[channel] = sess_details
                    sess_details.direction = plf.data.direction
                    sess_details.channel = channel
                if plf.data.amqp_error:
                    sess_details.counts.errors += 1

                if pname in ['begin', 'end', 'disposition']:
                    sess_details.session_frame_list.append(plf) # Accumulate to current session
                    if pname == 'end':
                        # end is closing this session
                        if sess_details.half_closed:
                            conn_details.EndChannel(plf.data.channel)
                        else:
                            sess_details.half_closed = True
                    else:
                        pass # begin handled above; disposition needs no action

                elif pname in ['attach']:
                    handle = plf.data.handle  # proton local handle
                    link_name = plf.data.link_short_name
                    link_name_unambiguous = link_name + "_" + str(handle)
                    error_was = plf.data.amqp_error
                    nl = sess_details.FindLinkByName(link_name, link_name_unambiguous, plf)
                    # if finding an ambiguous link name generated an error then propagate to session/connection
                    if not error_was and plf.data.amqp_error:
                        conn_details.counts.errors += 1
                        sess_details.counts.errors += 1
                    if nl is None:
                        # Creating a new link from scratch resulting in a half attached link pair
                        new_id = len(sess_details.link_list)
                        nl = LinkDetail(new_id, sess_details, sess_details.GetSeqNo(), link_name, plf.datetime)
                        sess_details.link_list.append(nl)
                        sess_details.link_name_to_detail_map[link_name_unambiguous] = nl
                        sess_details.link_name_conflict_map[link_name] = nl
                        nl.display_name = plf.data.link_short_name_popup
                        nl.direction = plf.data.direction
                        nl.is_receiver = plf.data.role == "receiver"
                        nl.first_address = plf.data.source if nl.is_receiver else plf.data.target
                    if plf.data.amqp_error:
                        nl.counts.errors += 1

                    if plf.data.direction_is_in():
                        # peer is creating link
                        nl.input_handle = handle
                        sess_details.DetachInputHandle(handle)
                        sess_details.input_handle_link_map[handle] = nl
                    else:
                        # local is creating link
                        nl.output_handle = handle
                        sess_details.DetachOutputHandle(handle)
                        sess_details.output_handle_link_map[handle] = nl
                    if plf.data.is_receiver:
                        nl.rcv_settle_mode = plf.data.rcv_settle_mode
                        nl.receiver_source_address = plf.data.source
                        nl.receiver_class = plf.data.link_class
                    else:
                        nl.snd_settle_mode = plf.data.snd_settle_mode
                        nl.sender_target_address = plf.data.target
                        nl.sender_class = plf.data.link_class
                    nl.frame_list.append(plf)

                elif pname in ['detach']:
                    ns = conn_details.FindSession(channel)
                    if ns is None:
                        conn_details.unaccounted_frame_list.append(plf)
                        continue
                    handle = plf.data.handle
                    nl = ns.FindLinkByHandle(handle, plf.data.direction_is_in())
                    ns.DetachHandle(handle, plf.data.direction_is_in())
                    if nl is None:
                        ns.session_frame_list.append(plf)
                    else:
                        if plf.data.amqp_error:
                            nl.counts.errors += 1
                        nl.frame_list.append(plf)

                elif pname in ['transfer', 'flow']:
                    ns = conn_details.FindSession(channel)
                    if ns is None:
                        conn_details.unaccounted_frame_list.append(plf)
                        plf.no_parent_link = True
                        continue
                    handle = plf.data.handle
                    nl = ns.FindLinkByHandle(handle, plf.data.direction_is_in())
                    if nl is None:
                        ns.session_frame_list.append(plf)
                        plf.no_parent_link = True
                    else:
                        if plf.data.amqp_error:
                            nl.counts.errors += 1
                        nl.frame_list.append(plf)
        # identify and index dispositions
        for conn in self.rtr.conn_list:
            id = self.rtr.conn_id(conn)
            conn_detail = self.conn_details[id]
            for sess in conn_detail.session_list:
                # for each disposition add state to disposition_map
                for splf in sess.session_frame_list:
                    if splf.data.name == "disposition":
                        if splf.data.direction == "<-":
                            sdispmap = sess.rx_rcvr_disposition_map if splf.data.is_receiver else sess.rx_sndr_disposition_map
                        else:
                            sdispmap = sess.tx_rcvr_disposition_map if splf.data.is_receiver else sess.tx_sndr_disposition_map
                        for sdid in range(int(splf.data.first), (int(splf.data.last) + 1)):
                            did = str(sdid)
                            if did in sdispmap:
                                sys.stderr.write("ERROR: Delivery ID collision in disposition map. connid:%s, \n" %
                                                 (splf.data.conn_id))
                            sdispmap[did] = splf

    def rollup_disposition_counts(self, state, conn, sess, link):
        if state is not None:
            if state.startswith("acce"):
                conn.accepted += 1
                sess.accepted += 1
                link.accepted += 1
            elif state.startswith("reje"):
                conn.rejected += 1
                sess.rejected += 1
                link.rejected += 1
            elif state.startswith("rele"):
                conn.released += 1
                sess.released += 1
                link.released += 1
            elif state.startswith("modi"):
                conn.modified += 1
                sess.modified += 1
                link.modified += 1
            else:
                pass    # Hmmm, some other disposition. TODO: count these

    def compute_settlement(self):
        for conn in self.rtr.conn_list:
            id = self.rtr.conn_id(conn)
            conn_detail = self.rtr.details.conn_details[id]
            for sess in conn_detail.session_list:
                for link in sess.link_list:
                    for plf in link.frame_list:
                        if plf.data.transfer:
                            tdid = plf.data.delivery_id
                            if plf.data.direction == "->":
                                rmap = sess.rx_rcvr_disposition_map
                                tmap = sess.rx_sndr_disposition_map
                            else:
                                rmap = sess.tx_rcvr_disposition_map
                                tmap = sess.tx_sndr_disposition_map
                            plf.data.disposition_display = self.resolve_settlement(link, plf,
                                                                                   rmap.get(tdid),
                                                                                   tmap.get(tdid))
                            if common.transfer_is_possibly_unsettled(plf):
                                if tdid not in link.unsettled_list:
                                    link.unsettled_list.append(tdid)
                                    link.counts.unsettled += 1
                                    sess.counts.unsettled += 1
                                    conn_detail.counts.unsettled += 1

                            else:
                                if not plf.data.transfer_more:
                                    if plf.data.transfer_presettled:
                                        link.counts.presettled += 1
                                        sess.counts.presettled += 1
                                        conn_detail.counts.presettled += 1
                                    else:
                                        self.rollup_disposition_counts(
                                            plf.data.final_disposition.data.disposition_state, conn_detail.counts, sess.counts, link.counts)
                                else:
                                    link.counts.more += 1
                                    sess.counts.more += 1
                                    conn_detail.counts.more += 1
                            if plf.data.transfer_aborted:
                                link.counts.aborted += 1
                                sess.counts.aborted += 1
                                conn_detail.counts.aborted += 1
                        if plf.data.flow_drain:
                            link.counts.drain += 1
                            sess.counts.drain += 1
                            conn_detail.counts.drain += 1

    def index_addresses(self):
        for conn in self.rtr.conn_list:
            id = self.rtr.conn_id(conn)
            conn_detail = self.rtr.details.conn_details[id]
            for sess in conn_detail.session_list:
                for link in sess.link_list:
                    self.comn.shorteners.short_addr_names.translate(link.first_address, False, link)

    def evaluate_credit(self):
        for conn in self.rtr.conn_list:
            id = self.rtr.conn_id(conn)
            conn_detail = self.rtr.details.conn_details[id]
            for sess in conn_detail.session_list:
                for link in sess.link_list:
                    # ignore links without starting attach
                    if link.frame_list[0].data.name != "attach":
                        link.counts.credit_not_evaluated += 1
                        sess.counts.credit_not_evaluated += 1
                        conn_detail.counts.credit_not_evaluated += 1
                        break
                    # process flaggage
                    look_for_sender_delivery_id = True
                    dir_of_xfer = ''
                    dir_of_flow = ''
                    current_delivery = 0 # next transfer expected id
                    delivery_limit = 0 # first unreachable delivery id from flow
                    n_attaches = 0
                    tod_of_second_attach = None
                    multiframe_in_progress = False
                    init_stall = True
                    credit_stall = False
                    tod_of_no_credit = None
                    tod_of_shutdown = None
                    # record info about initial attach
                    is_rcvr = link.frame_list[0].data.is_receiver
                    o_dir = link.frame_list[0].data.direction
                    # derive info about where to look for credit and transfer id
                    #  role dir  transfers flow w/credit case
                    #  ---- ---- --------- ------------- ----
                    #  rcvr  <-   ->        <-            A
                    #  rcvr  ->   <-        ->            B
                    #  sndr  <-   <-        ->            B
                    #  sndr  ->   ->        <-            A
                    #
                    if (((is_rcvr) and (o_dir == text.direction_in())) or
                        ((not is_rcvr) and (o_dir == text.direction_out()))):
                        # case A
                        dir_of_xfer = text.direction_out()
                        dir_of_flow = text.direction_in()
                    else:
                        # case B
                        dir_of_xfer = text.direction_in()
                        dir_of_flow = text.direction_out()

                    for plf in link.frame_list:
                        # initial credit delay starts at reception of second attach
                        if n_attaches < 2:
                            if plf.data.name == "attach":
                                n_attaches += 1
                                if n_attaches == 2:
                                    tod_of_second_attach = plf.datetime
                        if look_for_sender_delivery_id:
                            if plf.data.name == "attach" and not plf.data.is_receiver:
                                current_delivery = int(plf.data.described_type.dict.get("initial-delivery_count", "0"))
                                delivery_limit = current_delivery
                                look_for_sender_delivery_id = False

                        if plf.data.name == "flow":
                            if plf.data.direction == dir_of_flow:
                                # a flow in the normal direction updates the delivery limit
                                dc = plf.data.described_type.dict.get("delivery-count", "0")
                                lc = plf.data.described_type.dict.get("link-credit", "0")
                                delivery_limit = int(dc) + int(lc)  # TODO: wrap at 32-bits
                                if n_attaches < 2:
                                    # a working flow before sender attach - cancel initial stall
                                    init_stall = False
                                if init_stall:
                                    init_stall = False
                                    dur = plf.datetime - tod_of_second_attach
                                    link.counts.initial_no_credit_duration = dur
                                    sess.counts.initial_no_credit_duration += dur
                                    conn_detail.counts.initial_no_credit_duration += dur
                                if credit_stall and delivery_limit > current_delivery: # TODO: wrap
                                    credit_stall = False
                                    plf.data.web_show_str += " <span style=\"background-color:%s\">credit restored</span>" % common.color_of("no_credit")
                                    dur = plf.datetime - tod_of_no_credit
                                    link.counts.no_credit_duration += dur
                                    sess.counts.no_credit_duration += dur
                                    conn_detail.counts.no_credit_duration += dur
                            else:
                                # flow in the opposite direction updates the senders current delivery
                                # normally used to consume credit in response to a drain from receiver
                                current_delivery = int(plf.data.described_type.dict.get("initial-delivery_count", "0"))

                        elif plf.data.transfer:
                            if plf.data.direction == dir_of_xfer:
                                if not plf.data.transfer_more:
                                    # consider the transfer to have arrived when last transfer seen
                                    current_delivery += 1 # TODO: wrap at 32-bits
                                    if current_delivery == delivery_limit:
                                        link.counts.no_credit += 1
                                        sess.counts.no_credit += 1
                                        conn_detail.counts.no_credit += 1
                                        plf.data.transfer_exhausted_credit = True
                                        credit_stall = True
                                        plf.data.web_show_str += " <span style=\"background-color:%s\">no more credit</span>" % common.color_of("no_credit")
                                        tod_of_no_credit = plf.datetime
                                    else:
                                        pass # still have credit
                                    multiframe_in_progress = False
                                else:
                                    # transfers with 'more' set don't consume credit
                                    multiframe_in_progress = True
                            else:
                                pass   # transfer in wrong direction??

                        elif plf.data.name == "detach":
                            tod_of_shutdown = plf.datetime
                            break

                    # clean up lingering credit stall
                    if init_stall or credit_stall:
                        if tod_of_shutdown is None:
                            # find first end or close and call that shutdown time
                            for plf in sess.session_frame_list:
                                if plf.data.name == "end":
                                    tod_of_shutdown = plf.datetime
                                    break
                            if tod_of_shutdown is None:
                                for plf in conn_detail.unaccounted_frame_list:
                                    if plf.data.name == "close":
                                        tod_of_shutdown = plf.datetime
                                        break
                                if tod_of_shutdown is None:
                                    # Hmmm, no shutdown. Use last link frame
                                    tod_of_shutdown = link.frame_list[-1].datetime
                        if tod_of_second_attach is None:
                            # Hmmm, no second attach. Use first link frame time
                            tod_of_second_attach = link.frame_list[0].datetime
                        if init_stall:
                            dur = tod_of_shutdown - tod_of_second_attach
                            link.counts.initial_no_credit_duration = dur
                            sess.counts.initial_no_credit_duration += dur
                            conn_detail.counts.initial_no_credit_duration += dur
                        if credit_stall: # TODO: wrap
                            dur = tod_of_shutdown - tod_of_no_credit
                            link.counts.no_credit_duration += dur
                            sess.counts.no_credit_duration += dur
                            conn_detail.counts.no_credit_duration += dur

                    # record multiframe transfer that didn't complete
                    if multiframe_in_progress:
                        link.counts.incomplete += 1
                        sess.counts.incomplete += 1
                        conn_detail.counts.incomplete += 1

    def show_html(self):
        for conn in self.rtr.conn_list:
            id = self.rtr.conn_id(conn)
            conn_detail = self.rtr.details.conn_details[id]
            conn_frames = self.rtr.conn_to_frame_map[id]
            print("<a name=\"cd_%s\"></a>" % id)
            # This lozenge shows/hides the connection's data
            print("<a href=\"javascript:toggle_node('%s_data')\">%s%s</a>" %
                  (id, text.lozenge(), text.nbsp()))
            dir = self.rtr.conn_dir[id] if id in self.rtr.conn_dir else ""
            peer = self.rtr.conn_peer_display.get(id, "")  # peer container id
            peerconnid = self.comn.conn_peers_connid.get(id, "")
            # show the connection title
            print("%s %s %s %s (nFrames=%d) %s<br>" % \
                  (id, dir, peerconnid, peer, len(conn_frames), conn_detail.counts.show_html()))
            # data div
            print("<div id=\"%s_data\" style=\"display:none; margin-bottom: 2px; margin-left: 10px\">" % id)

            # unaccounted frames
            print("<a href=\"javascript:toggle_node('%s_data_unacc')\">%s%s</a>" %
                  (id, text.lozenge(), text.nbsp()))
            # show the connection-level frames
            errs = sum(1 for plf in conn_detail.unaccounted_frame_list if plf.data.amqp_error)
            print("Connection-based entries %s<br>" % self.format_errors(errs))
            print("<div id=\"%s_data_unacc\" style=\"display:none; margin-bottom: 2px; margin-left: 10px\">" % id)
            for plf in conn_detail.unaccounted_frame_list:
                print(plf.adverbl_link_to(), plf.datetime, plf.data.direction, peer, plf.data.web_show_str, "<br>")
            print("</div>")  # end unaccounted frames

            # loop to print session details
            for sess in conn_detail.session_list:
                # show the session 'toggle goto' and title
                print("<a href=\"javascript:toggle_node('%s_sess_%s')\">%s%s</a>" %
                      (id, sess.conn_epoch, text.lozenge(), text.nbsp()))
                print("Session %s: channel: %s, peer channel: %s; Time: start %s, Counts: frames: %d %s<br>" % \
                      (sess.conn_epoch, sess.channel, sess.peer_chan, sess.time_start, \
                       sess.FrameCount(), sess.counts.show_html()))
                print("<div id=\"%s_sess_%s\" style=\"display:none; margin-bottom: 2px; margin-left: 10px\">" %
                      (id, sess.conn_epoch))
                # show the session-level frames
                errs = sum(1 for plf in sess.session_frame_list if plf.data.amqp_error)
                print("<a href=\"javascript:toggle_node('%s_sess_%s_unacc')\">%s%s</a>" %
                      (id, sess.conn_epoch, text.lozenge(), text.nbsp()))
                print("Session-based entries %s<br>" % self.format_errors(errs))
                print("<div id=\"%s_sess_%s_unacc\" style=\"display:none; margin-bottom: 2px; margin-left: 10px\">" %
                      (id, sess.conn_epoch))
                for plf in sess.session_frame_list:
                    print(plf.adverbl_link_to(), plf.datetime, plf.data.direction, peer, plf.data.web_show_str, "<br>")
                print("</div>")  # end <id>_sess_<conn_epoch>_unacc
                # loops to print session link details
                # first loop prints link table
                print("<table")
                print("<tr><th>Link</th> <th>Dir</th> <th>Role</th>  <th>Address</th>  <th>Class</th>  "
                      "<th>snd-settle-mode</th>  <th>rcv-settle-mode</th>  <th>Start time</th>  <th>Frames</th> "
                      "<th>Counts</th> </tr>")
                for link in sess.link_list:
                    # show the link toggle and title
                    showthis = ("<a href=\"javascript:toggle_node('%s_sess_%s_link_%s')\">%s</a>" %
                                (id, sess.conn_epoch, link.session_seq, text.lozenge()))
                    visitthis = ("<a href=\"#%s_sess_%s_link_%s_data\">%s</a>" %
                                (id, sess.conn_epoch, link.session_seq, link.display_name))
                    role = "receiver" if link.is_receiver else "sender"
                    print("<tr><td>%s %s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>"
                          "<td>%s</td><td>%d</td><td>%s</td> </tr>" % \
                          (showthis, visitthis, link.direction, role, link.first_address,
                           (link.sender_class + '-' + link.receiver_class), link.snd_settle_mode,
                           link.rcv_settle_mode, link.time_start, link.FrameCount(),
                           link.counts.show_html()))
                print("</table>")
                # second loop prints the link's frames
                for link in sess.link_list:
                    print(
                        "<div id=\"%s_sess_%s_link_%s\" style=\"display:none; margin-top: 2px; margin-bottom: 2px; margin-left: 10px\">" %
                        (id, sess.conn_epoch, link.session_seq))
                    print("<a name=\"%s_sess_%s_link_%s_data\"></a>" %
                                (id, sess.conn_epoch, link.session_seq))
                    print("<h4>Connection %s Session %s Link %s</h4>" %
                          (id, sess.conn_epoch, link.display_name))
                    for plf in link.frame_list:
                        print(plf.adverbl_link_to(), plf.datetime, plf.data.direction, peer, plf.data.web_show_str,
                              plf.data.disposition_display, "<br>")
                    print("</div>")  # end link <id>_sess_<conn_epoch>_link_<sess_seq>

                print("</div>")  # end session <id>_sess_<conn_epoch>

            print("</div>")  # end current connection data


if __name__ == "__main__":

    try:
        pass
    except:
        traceback.print_exc(file=sys.stdout)
        pass
