#!/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 ifstats
import iperf
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 _Resource(name):
  return os.path.join(os.path.dirname(os.path.abspath(__file__)), name)


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

  raw = []

  with open(_Resource(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."""
  if channels: return

  with open(_Resource(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."""
  LoadNRates()

  # 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 Channel(text_channel):
  """Given a text channel spec like 149,+1 return the central freq and width."""
  LoadChannels()

  if ',' in text_channel:
    base, offset = text_channel.split(',')
    freq = channels[int(base)]
    offset = int(offset)
    return (2 * freq + offset * 20) / 2, 40
  else:
    return channels[int(text_channel)], 20


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 = os.path.basename(report_dir).split('-')
  line = [int(steps)]

  system, cache = ifstats.Restore(report_dir)
  result = ifstats.Parse(system, cache)
  if system == 'Darwin':
    airport = result.get('link')
    channel, width = Channel(airport['channel'])
    shared = 0
    overlap = 0

    scan = result.get('scan')
    if len(scan) > 1:
      for row in scan[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 += [channel, width, rssi, noise, shared, overlap - shared]
  elif system == 'Linux':
    iwlink = result.get('link')
    signal = int(iwlink.get('signal', '0 dBm').split()[0])
    channel = int(iwlink.get('freq'))
    width = 20
    m = re.search(r'(\d+)MHz', iwlink.get('tx bitrate'), flags=re.I)
    if m:
      width = int(m.group(1))

    # Noise and contention not yet gathered in samples run on Linux systems.
    line += [channel, width, signal, None, None, None]

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

  # If the initial ping test fails, we won't collect performance information.
  # deal with this gracefully.
  ips = iperf.Restore(report_dir)
  for perf in [iperf.ParseIperfTCP(ips.get('iperf', '')),
               iperf.ParseIperfUDP(ips.get('iperfu', ''))]:
    line += [perf.get('bandwidth'), perf.get('bandwidth_unit')]

  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:
    for jname in extra[:1]:
      jname = os.path.realpath(jname)
      with open(jname) as journal:
        for line in journal:
          lines += [ReportLine(os.path.join(os.path.dirname(jname),
                                            line.strip()))]

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

  header = ['Steps', 'Channel', 'Width', 'RSSI', 'Noise', 'Shared',
            'Interfering', 'MCS', 'PHY', 'TCP BW', '(Units)', 'UDP BW',
            '(Units)']
  writer = csv.writer(sys.stdout, delimiter='\t', quoting=csv.QUOTE_MINIMAL)
  writer.writerow(header)
  writer.writerows(lines)


if __name__ == '__main__':
  main()
