#!/usr/bin/python
# Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed 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.
#
"""UDP test host.

This is the host-side implementation of a UDP test tool to evaluate the speed
of a connection using bursts of UDP traffic
"""
import select
import socket
import struct
import sys
import time

import options

try:
  import monotime
except ImportError:
  pass
try:
  monotime = time.monotime
except AttributeError:
  monotime = time.time

optspec = """
udp_test_host.py [options...]
--
p,port=         Specify a port to use. [5001]
s,size=         Specify the packet size [1472]
"""


def main():
  o = options.Options(optspec)
  opt, _, _ = o.parse(sys.argv[1:])

  port = int(opt.port)
  send_rate = 1000.0  # Hz
  current_index = 0
  timeout_val = 10

  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  sock.bind(('', port))

  client_addr = ('', 0)
  last_client_time = 0
  last_packets_sent = 0
  last_packets_recv = 0
  remainder_time = 0

  cycle_counter = 0
  cycle_time = monotime()
  msg_length = int(opt.size)
  counter_msg = bytearray('7' * msg_length)
  while True:
    # Account for processing time
    sock_status, _, _ = select.select([sock], [], [], remainder_time)
    if sock_status:
      host_time = monotime()
      data, addr = sock.recvfrom(65536)
      magic, pack_type, server_count, client_count, new_time = struct.unpack(
          '!4s4siid', data)
      if magic != 'TPDO' or pack_type != 'UPDT':
        print 'Invalid Packet'
        continue
      if addr != client_addr:
        current_index = 0
        send_rate = 1000.0  # Hz

        client_addr = addr
        cycle_time = monotime()
        cycle_counter = 0
        # Keeps track of last time client was heard from
        last_packets_sent = last_packets_recv = 0
        last_client_time = new_time
        host_time = monotime()
        print 'connection established with %s\n' % client_addr[0]
      else:
        # Calculate metrics for user
        cycle_length = new_time - last_client_time
        measured_pack_sent = (server_count - last_packets_sent) / cycle_length
        measured_send_rate = measured_pack_sent * msg_length * 8 / 1000000
        measured_recv_rate = ((client_count - last_packets_recv) /
                              cycle_length * msg_length * 8 / 1000000)
        if server_count <= last_packets_sent:
          success_rate = 0
        else:
          success_rate = (float(client_count - last_packets_recv) /
                          (server_count - last_packets_sent))

        print ('\nAttempted Rate: %.2fMbps, Sending Rate: %.2fMbps, '
               'Receive Rate: %.2fMbps, Success Rate: %.2f%%'
               % (send_rate * msg_length * 8 / 1000000,
                  measured_send_rate,
                  measured_recv_rate,
                  success_rate * 100))

        cycle_time = monotime()
        cycle_counter = 0
        if float(success_rate) > 0.9:
          send_rate = 1.1 * measured_pack_sent
        elif float(success_rate) < 0.8:
          send_rate = 0.9 * measured_pack_sent
        else:
          send_rate = measured_pack_sent

        # Prevent the host from not sending any packets.
        if send_rate <= 0:
          send_rate = 10
        last_packets_recv = client_count
        last_packets_sent = server_count
        last_client_time = new_time

    elif client_addr != ('', 0):
      # No packets from client received
      burst_counter = 0
      while True:
        remainder_time = (cycle_counter + 1) / send_rate - (monotime() -
                                                            cycle_time)
        if remainder_time > 0:
          break
        cycle_counter += 1
        current_index += 1
        counter_msg[0:12] = struct.pack('!4s4si', 'TPDO', 'RNNG', current_index)
        sock.sendto(counter_msg, client_addr)
        burst_counter += 1
        if not current_index % (int(send_rate/10) + 1):
          sys.stdout.write('.')
          sys.stdout.flush()
        if monotime() - host_time > timeout_val:
          client_addr = ('', 0)
          sys.stderr.write('\nconnection lost with client\n')
          remainder_time = 0
          break
        if burst_counter > 1000:
          remainder_time = 0
          break

if __name__ == '__main__':
  main()

