#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import argparse
import struct
from contextlib import closing
import socket
import errno
import time
import sys
from psas_packet import io
from psas_packet import messages

SEQN = messages.MESSAGES['SEQN']

def replay(log):

    with closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as sock:
        sock.bind(('', 0))
        sock.connect(('127.0.0.1', 35001))

        with io.BinFile(log) as log:
            seq = 0
            cur_seq = -1
            file_time = 0
            last_seq_time = 0
            now = time.time()
            last_pack_sent = 0
            buff = b''
            for fourcc, raw in log.scan():
                # scan sequnce numbers
                if fourcc == SEQN.fourcc:
                    fourcc, timestamp, length = messages.HEADER.decode(raw[:messages.HEADER.size])
                    data = SEQN.decode(raw[messages.HEADER.size:])
                    seq = data['Sequence']
                    file_time = timestamp
                    if seq != cur_seq:
                        # Wait and send
                        if len(buff) > 0:
                            now = time.time()
                            packet_delay = (file_time - last_seq_time)/1e9
                            real_delay = now - last_pack_sent
                            wait_time = packet_delay - real_delay
                            if wait_time > 0:
                                time.sleep(wait_time)
                            try:
                                sock.send(buff)
                            except socket.error as e:
                                if e.errno == errno.ECONNREFUSED:
                                    pass
                                else:
                                    print(e)
                                    raise
                            sys.stdout.write("  Sequence No.: {0}\r".format(seq))
                            sys.stdout.flush()
                            last_pack_sent = time.time()

                        # reset
                        last_seq_time = file_time
                        buff = b''
                        buff += struct.pack('!L', seq)
                        cur_seq = seq
                else:
                    # copy log
                    buff += raw

            # flush last packet
            now = time.time()
            packet_delay = (file_time - last_seq_time)/1e9
            real_delay = now - last_pack_sent
            wait_time = packet_delay - real_delay
            if wait_time > 0:
                time.sleep(wait_time)
            try:
                sock.send(buff)
            except socket.error as e:
                if e.errno == errno.ECONNREFUSED:
                    pass
                else:
                    print(e)
                    raise

            sys.stdout.write("  Sequence No.: {0}\n".format(seq))
            #print(cur_seq, len(buff), packet_delay, real_delay, wait_time)

    print("EOF")


if __name__ == '__main__':
    parser = argparse.ArgumentParser(prog='replaylog')
    parser.add_argument('logfile', type=argparse.FileType('rb'), help="Log file to read")

    args = vars(parser.parse_args())

    replay(args['logfile'])
