#!/usr/bin/env python3

#
# 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 typing import List
import optparse
import fileinput
import json
import re
import sys

"""
This program accepts input for a modified Scraper and produces output to create sequence diagrams
at sequencediagram.org.
"""

IDX_DATETIME = 0
IDX_NAME_LEFT = 1
IDX_DIR = 2
IDX_NAME_RIGHT = 3
IDX_PERFORMATIVE = 4
IDX_ROUTER_LINE = 5

# Exactly how to predict how much 'space' asynchronous messages take is vague.
MAGIC_SPACE_NUMBER = 1   # tested with entryspacing 0.1

class log_record:
    def __init__(self, index, line):
        # print("DEBUG input line: ", index, line)
        dateandtime, name_left, direction, name_right, perf, router_line, dummy = line.split('|')
        self.dateandtime = dateandtime.strip()
        self.time = self.dateandtime.split(' ')[1]
        self.index = index
        self.name_left = name_left.strip()
        self.direction = direction.strip()
        self.name_right = name_right.strip()
        self.performative = perf.strip()
        self.router_line = router_line.strip() # diag
        self.peer_log_rec = None
        dir_out = (direction == '->') # name_left -> name_right
        self.sentby = name_left.strip() if dir_out else name_right.strip()
        self.rcvdby = name_right.strip() if dir_out else name_left.strip()

    def absorb_peer_rec(self, peer_rec):
        '''
        Given peer_rec, see if it is the receiving side of
        this log_rec being sent. If so then cross-link the
        records and return true.
        :param peer_rec:
        :return:
        '''
        valid_peer = self.name_left == peer_rec.name_right and \
            self.name_right == peer_rec.name_left and \
            self.direction != peer_rec.direction and \
            self.performative.startswith(peer_rec.performative) and \
            self.peer_log_rec is None and \
            peer_rec.peer_log_rec is None
        if not valid_peer:
            return False
        self.peer_log_rec = peer_rec
        peer_rec.peer_log_rec = self
        return True

    def show_for_sdorg(self, showtime):
        # A single sd.org vector consumes one or two log lines.
        #  One if from an external actor.
        #  Two if a message goes between routers.
        # Leave space where the message is supposed to land in the receiving routers
        if self.peer_log_rec is None:
            if showtime:
                print("%s->%s:%s %s" % (self.sentby, self.rcvdby, self.time, self.performative))
            else:
                print("%s->%s:%s" % (self.sentby, self.rcvdby, self.performative))
        else:
            if self.peer_log_rec.index > self.index:
                linediff = int(self.peer_log_rec.index) - int(self.index)
                space = -MAGIC_SPACE_NUMBER * (linediff - 1)
                if showtime:
                    print("%s->(%s)%s:%s %s" %(self.sentby, str(linediff), self.rcvdby, self.time, self.performative))
                else:
                    print("%s->(%s)%s:%s" % (self.sentby, str(linediff), self.rcvdby, self.performative))
                print("space %s" % (str(space)))
            else:
                print("space %d" % MAGIC_SPACE_NUMBER)

    def sender_receiver(self):
        # Return sender receiver
        return self.sentby, self.rcvdby

    def diag_dump(self):
        cmn = ("index: %d, dateandtime: %s, sentby: %s, rcvdby: %s, performative: %s, router_line: %s" %
               (self.dateandtime, self.index, self.sentby, self.rcvdby, self.performative, self.router_line))
        if self.peer_log_rec is None:
            print(cmn)
        else:
            print("%s, PEER MATCH peer_index: %s, peer_router_log_line: %s" %
                  (cmn, self.peer_log_rec.index, self.peer_log_rec.router_line))


def split_log_file(filename):
    '''
    Given a filename, read the file into an array of lines
    :param filename:
    :return:
    '''
    if filename == "STDIN" or filename == "" or filename == "-":
        log = sys.stdin
        log_lines = log.read().split("\n")
    else:
        log = open(filename, 'r')
        log_lines = log.read().split("\n")
        log.close()
    return log_lines


def match_logline_pairs(log_recs):
    '''
    Given a log line that might be the source of a message to another router,
    search the list of remaining log lines and try to find the router that received
    this message. Then hook them together.
    The cut of Scraper output presented as input to this program may not be complete.
    Messages for which there is no 'match' are drawn as horizontal lines.
    :param log_lines:
    :return:
    '''
    for idx in range(len(log_recs)-2):
        for idx2 in range(idx+1, len(log_recs)-1):
            if log_recs[idx].absorb_peer_rec(log_recs[idx2]):
                break


if __name__ == "__main__":
    parser = optparse.OptionParser(usage="%prog [options]",
                                   description="cooks a scraper log snippet into sequence diagram source")
    parser.add_option("-f", "--filename", action="append", help="logfile to use or - for stdin")
    parser.add_option('--timestamp', '-t',
                      action='store_true',
                      help='Include HH:MM:SS.ssssss in output')

    (opts, args) = parser.parse_args()
    if not opts.filename:
        opts.filename = ["-"]

    log_recs = []
    for logfile in opts.filename:
        # print("Parsing: %s" % logfile)
        log_lines = split_log_file(logfile)
        if len(log_lines) >= 2:
            index = 0
            for logline in log_lines:
                if len(logline) > 0:
                    log_recs.append( log_record(index, logline) )
                    index += 1
            match_logline_pairs(log_recs)

            # print senders and receivers marking as actor or participant
            names = set()
            for log_rec in log_recs:
                sndr, rcvr = log_rec.sender_receiver()
                if sndr is not None:
                    names.add(sndr)
                if rcvr is not None:
                    names.add(rcvr)
            for name in names:
                if name.startswith("peer"):
                    print("actor %s" % name)
                else:
                    print("participant %s" % name)
            print()

            # process the list of records
            for log_rec in log_recs:
                log_rec.show_for_sdorg(opts.timestamp)

            # diag dump
            #print("\nDiag dump")
            #for log_rec in log_recs:
            #    log_rec.diag_dump()
        else:
            print("Log file has fewer than two lines. I give up.")
        print()
