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

# A single router log file may contain data from multiple instances of
# that router booting and running. Thus there may be several different
# connections labeled [0] and these connections may be to different
# routers on each run.
#
# The 'router' class defined here represents a single boot-and-run
# instance from the log file.
#

from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

import sys
import traceback
import datetime

import amqp_detail
import common
import text

class RestartRecord():
    def __init__(self, _router, _line, _lineno):
        self.router = _router
        self.line = _line
        self.lineno = _lineno
        try:
            self.datetime = datetime.datetime.strptime(self.line[:26], '%Y-%m-%d %H:%M:%S.%f')
        except:
            self.datetime = datetime.datetime(1970, 1, 1)

    def __repr__(self):
        return "%d instance %d start %s #%d" % (self.router.log_index, self.router.instance,
                                                self.datetime, self.lineno)

class Router():
    '''A single dispatch boot-and-run instance from a log file'''

    def __init__(self, _fn, _log_index, _instance):
        self.fn = _fn                 # log file name
        self.log_index = _log_index   # 0=A, 1=B, ...
        self.instance = _instance     # log file instance of router
        self.iletter = common.log_letter_of(self.log_index)  # A
        self.iname = self.iletter + str(self.instance)       # A0

        # discovered Container Name
        self.container_name = None

        # discovered Version
        self.version = None

        # discovered mode
        self.mode = None

        # restart_rec - when this router was identified in log file
        self.restart_rec = None

        # lines - the log lines as ParsedLogLine objects
        self.lines = []

        # conn_list - List of connections discovered in log lines
        # Sorted in ascending order and not necessarily in packed sequence.
        self.conn_list = []

        # conn_log_lines - count of log lines per connection
        self.conn_log_lines = {}

        # conn_transfer_bytes - count of bytes transfered over this connection
        self.conn_xfer_bytes = {}

        # connection_to_frame_map
        self.conn_to_frame_map = {}

        # conn_peer - peer container long name
        #   key= connection id '1', '2'
        #   val= original peer container name
        self.conn_peer = {}

        # conn_peer_display - peer container display name
        #   key= connection id '1', '2'
        #   val= display name
        # Peer display name shortened with popup if necessary
        self.conn_peer_display = {}

        # conn_peer_connid - display value for peer's connection id
        #   key= connection id '1', '2'
        #   val= peer's connid 'A.0_3', 'D.3_18'
        self.conn_peer_connid = {}

        # conn_dir - arrow indicating connection origin direction
        #   key= connection id '1', '2'
        #   val= '<-' peer created conn, '->' router created conn
        self.conn_dir = {}

        # router_ls - link state 'ROUTER_LS (info)' lines
        self.router_ls = []

        # open and close times
        self.conn_open_time = {}   # first log line with [N] seen
        self.conn_close_time = {}  # last close log line seen

        # details: for each connection, for each session, for each link, whaaa?
        self.details = None


    def discover_connection_facts(self, comn):
        '''
        Discover all the connections in this router-instance log
        For each connection:
         * determine connection direction
         * discover name of peer container
         * generate html to use to display the peer nickname
         * count log lines
         * count transfer bytes
        :param comn:
        :return:
        '''
        for item in self.lines:
            if item.data.is_scraper:
                # scraper lines are pass-through
                continue
            conn_num = int(item.data.conn_num)
            id = item.data.conn_id           # full name A0_3
            if conn_num not in self.conn_list:
                cdir = ""
                if item.data.direction != "":
                    cdir = item.data.direction
                else:
                    if "Connecting" in item.data.web_show_str:
                        cdir = text.direction_out()
                    elif "Accepting" in item.data.web_show_str:
                        cdir = text.direction_in()
                self.conn_list.append(conn_num)
                self.conn_to_frame_map[id] = []
                self.conn_dir[id] = cdir
                self.conn_log_lines[id] = 0   # line counter
                self.conn_xfer_bytes[id] = 0  # byte counter
                self.conn_open_time[id] = item
            self.conn_to_frame_map[id].append(item)
            # inbound open handling
            if item.data.name == "open" and item.data.direction == text.direction_in():
                if item.data.conn_id in self.conn_peer:
                    sys.exit('ERROR: file: %s connection %s has multiple connection peers' % (
                    self.fn, id))
                self.conn_peer[id] = item.data.conn_peer
                self.conn_peer_display[id] = comn.shorteners.short_peer_names.translate(
                    item.data.conn_peer, True)
            # close monitor
            if item.data.name == "close":
                self.conn_close_time[id] = item
            # connection log-line count
            self.conn_log_lines[id] += 1
            # transfer byte count
            if item.data.name == "transfer":
                self.conn_xfer_bytes[id] += int(item.data.transfer_size)
        self.conn_list = sorted(self.conn_list)
        self.details = amqp_detail.AllDetails(self, comn)

    def conn_id(self, conn_num):
        '''
        Given this router's connection number return the global connection id
        :param conn_num: connection number
        :return: conn_id in the for A0_3
        '''
        return self.iname + "_" + str(conn_num)

    def is_interior(self):
        return self.mode == "interior"


def which_router_tod(router_list, at_time):
    '''
    Find a router in a list based on time of day
    :param router_list: a list of Router objects
    :param at_time: the datetime record identifying the router
    :return: tuple: (a router from the list or None, router index)
    '''
    if len(router_list) == 0:
        return (None, 0)
    if len(router_list) == 1:
        return (router_list[0], 0)
    for i in range(1, len(router_list)):
        if at_time < router_list[i].restart_rec.datetime:
            return (router_list[i-1], i-1)
    return (router_list[-1], len(router_list)-1)

def which_router_id_tod(routers, id, at_time):
    '''
    Find a router by container_name and time of day
    :param routers: a list of router instance lists
    :param id: the container name
    :param at_time: datetime of interest
    :return: the router that had that container name at that time; None if not found
    '''
    for routerlist in routers:
        if routerlist[0].container_name == id:
            return which_router_tod(routerlist, at_time)
    return (None, 0)



if __name__ == "__main__":
    try:
        pass
    except:
        traceback.print_exc(file=sys.stdout)
        pass
