#!/usr/bin/env python

"""report: make a table summarizing output from one or more runs of `sample`."""

from collections import Counter
import csv
import os
import re
import sys
import options

optspec = """
report [options...] <journal>
--
r,report_dir=  path to a single report directory to be parsed
"""

NFILE = 'n-datarates.tsv'
nrates = {}

CHANNELFILE = 'channels.tsv'
channels = {}


def LoadNRates():
  """Loads 802.11n coding and data rates into a global variable."""
  if nrates: return

  raw = []

  with open(NFILE, 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter='\t')
    next(reader)  # skip header row when reading by machine
    for mcs, width, gi, rate in reader:
      raw.append([int(mcs), int(width), int(gi), float(rate)])

  # Load global table, computing MCS 8-31 statistics from MCS 0-7.
  for mcs, width, gi, rate in raw:
    for i in range(4):
      nrates[(8*i + mcs, width, gi)] = rate * (i + 1)


def LoadChannels():
  """Load 802.11n channels and frequencies into a global variable."""

  with open(CHANNELFILE, 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter='\t')
    next(reader)

    for channel, freq in reader:
      channels[int(channel)] = int(freq)


def ParseMCSFile(outfile, width=20):
  """Extract MCS and PHY rate statistics from an MCS report file."""

  # assume long guard interval
  guard = 800

  counter = Counter()
  for line in outfile:
    for tok in line.split():
      if tok == '.': continue

      mcs = int(tok)
      counter[mcs] += 1

  phy = 0.0
  alltimes = 0
  for mcs, times in counter.iteritems():
    phy += nrates[(mcs, width, guard)] * times
    alltimes += times

  return counter.most_common()[0][0], phy / alltimes


def ParseIperf(out, udp=False):
  """Parse output written by an `iperf` run into structured data."""
  pattern = (r'\[(.{3})\]\s+(?P<interval>.*?sec)\s+(?P<transfer>.*?Bytes|bits)'
             r'\s+(?P<bandwidth>.*?/sec)')
  if udp:
    pattern += r'\s+(?P<jitter>.*?s)\s+(?P<datagrams>.*)'

  iperf_re = re.compile(pattern)

  for line in out.splitlines():
    match = iperf_re.match(line)
    if match:
      iperf = match.groupdict()
      iperf['bandwidth'] = float(iperf['bandwidth'].split()[0])
      return iperf

  return {}


def ParseIperfTCP(out):
  """ParseIperfTCP parses the output of TCP `iperf` runs."""
  # sample line: [  4]  0.0-10.0 sec   245 MBytes   206 Mbits/sec
  return ParseIperf(out)


def ParseIperfUDP(out):
  """ParseIperfUDP parses the output of UDP `iperf` runs."""
  # pylint: disable=line-too-long
  # sample line: [  5]  0.0-10.0 sec  1.25 MBytes  1.05 Mbits/sec   0.593 ms    0/  893 (0%)
  return ParseIperf(out, udp=True)


def Channel(text_channel):
  """Given a text channel spec like 149,+1 return the central freq and width."""
  if ',' in text_channel:
    base, offset = text_channel.split(',')
    freq = channels[int(base)]
    offset = int(offset)
    return (freq + offset * 20) / 2, 40
  else:
    return channels[int(text_channel)], 20


def ParseAirportI(output):
  """Parse output of `airport -I` and return it as a dictionary."""
  result = {}
  for line in output.splitlines():
    try:
      key, value = [cell.strip() for cell in line.split(':', 1)]
      if key in ['agrCtlRSSI', 'agrCtlNoise']:
        result[key] = int(value)
      else:
        result[key] = value
    except ValueError:
      continue

  return result


def ParseAirportScan(output):
  """Parse output of `airport -s` and return it as a dictionary."""
  # This is a simple fixed-width format.
  header = ['SSID', 'BSSID', 'RSSI', 'CHANNEL', 'HT', 'CC',
            'SECURITY (auth/unicast/group)']
  result = []

  chre = re.compile(r'\d+(?:,\+|-\d+)?')
  for line in output.splitlines():
    ssid, bssid, rssi, channel, ht, cc, security = (
        [cell.strip() for cell in (line[:32], line[33:50], line[51:55],
                                   line[56:63], line[64:66], line[67:69],
                                   line[70:])])

    # the scan sometimes includes comment lines. assume that anything that has
    # a valid channel isn't a comment line.
    if chre.match(channel):
      result += [[ssid, bssid, int(rssi), channel, ht, cc, security]]

  return [header] + result


def ParseIwLink(output):
  """Parse output of `iw dev <devname> link` and return it as a dictionary."""
  ol = output.splitlines()

  # BSSID is in the first line, in an idiosyncratic format.
  # sample: Connected to d8:c7:c8:d7:72:30 (on wlan0)
  m = re.search(r'(\w{2}:){5}\w{2}', ol[0])
  if m:
    result = {'BSSID': m.group(0)}
  else:
    raise ValueError('dev was not connected.')

  for line in ol[1:]:
    try:
      key, value = line.split(':', 1)
      result[key.strip()] = value.strip()
    except ValueError:
      continue

  return result


def ParseIpAddr(output):
  """Parse output of one-line `ip addr` and return it as a dictionary."""
  ol = output.splitlines()
  result = {}
  for line in ol:
    _, interface, _, addr, _ = line.split(None, 4)
    result[interface] = addr

  return result


def Overlap(c1, w1, c2, w2):
  """Return True if two WiFi channels overlap, or False otherwise."""
  # TODO(willangley): replace with code from Waveguide
  b1 = c1 - w1 / 2
  t1 = c1 + w1 / 2
  b2 = c2 - w2 / 2
  t2 = c2 + w2 / 2

  return ((b1 <= b2 <= t1) or (b2 <= b1 <= t2)
          or (b1 <= t2 <= t1) or (b2 <= t1 <= t2))


def ReportLine(report_dir):
  """Condense the output of a sample.py run into a one-line summary report."""
  _, _, steps = report_dir.split('-')
  line = [int(steps)]

  # Reports generated on Mac have 'airport'
  apath = os.path.join(report_dir, 'airport')
  if os.path.isfile(apath):
    with open(apath) as ai:
      airport = ParseAirportI(ai.read())

    channel, width = Channel(airport['channel'])
    shared = 0
    overlap = 0

    cpath = os.path.join(report_dir, 'airportscan')
    if os.path.exists(cpath):
      with open(cpath) as ac:
        for row in ParseAirportScan(ac.read())[1:]:
          oc, ow = Channel(row[3])
          if channel == oc and width == ow:
            shared += 1
          if Overlap(channel, width, oc, ow):
            overlap += 1

    rssi = airport['agrCtlRSSI']
    noise = airport['agrCtlNoise']
    line += [rssi, noise, shared, overlap - shared]

  else:
    # assume the report was generated on Linux.
    with open(os.path.join(report_dir, 'iwlink')) as il:
      iwlink = ParseIwLink(il.read())

    signal = int(iwlink.get('signal', '0 dBm').split()[0])
    line += [signal, '', '', '']  # Noise and contention not yet gathered in
                                  # samples run on Linux systems.

    width = 20
    m = re.search(r'(\d+)Mhz', iwlink.get('tx bitrate'))
    if m:
      width = int(m.group(1))

  mpath = os.path.join(report_dir, 'mcs')
  if os.path.isfile(mpath):
    with open(os.path.join(report_dir, 'mcs')) as mf:
      line += ParseMCSFile(mf, width)
  else:
    line += ['', '']

  it = open(os.path.join(report_dir, 'iperf'))
  iu = open(os.path.join(report_dir, 'iperfu'))

  tcp_perf = ParseIperfTCP(it.read())
  udp_perf = ParseIperfUDP(iu.read())
  line += [tcp_perf.get('bandwidth'), udp_perf.get('bandwidth')]

  iu.close()
  it.close()

  return line


def main():
  o = options.Options(optspec)
  (opt, _, extra) = o.parse(sys.argv[1:])
  if len(extra) > 1:
    o.fatal('expected at most one journal name.')

  LoadNRates()
  LoadChannels()

  lines = []
  if opt.report_dir:
    lines += [ReportLine(opt.report_dir)]

  if extra:
    with open(extra[0]) as journal:
      for line in journal:
        lines += [ReportLine(line.strip())]

  if len(lines) < 1:
    o.fatal("didn't find any samples. did you supply at least one report dir"
            ' or journal?')

  print '\t'.join(['Steps', 'RSSI', 'Noise', 'Shared', 'Interfering', 'MCS',
                   'PHY', 'TCP', 'UDP'])
  for line in lines:
    print '\t'.join(str(i) for i in line)


if __name__ == '__main__':
  main()
