#!/usr/bin/python2.7
"""sample: measure wireless performance and write a report to the filesystem."""

import atexit
import collections
import functools
import logging
import os
import pipes
import platform
import subprocess
import sys
import time

from fabric import api
from fabric import network
from fabric import utils

import ifstats
import ifstats_skids
import iperf
import isostream
import options
import tcpdump

optspec = """
sample [options...]
--
B,bind=              interface IP to bind during iperf runs
d,destination=       host to run tests against [192.168.1.143]
s,steps=             number of steps test was run from [10]
j,journal=           append to journal tracking a series of test runs
i,interface=         interface to use for outgoing connections
m,monitor            try to monitor wireless traffic using `tcpdump`
M,monitor-interface= override default interface for monitoring traffic.
no-filter            don't attempt to filter packets seen on monitor interface
r,remote=            comma-separated list of remote hosts to run tests on
S,skid=              IP address of the skid used to reach the network
t,time=              length of time in seconds to run isostream test for [50]
"""


class FabricLoggingHandler(logging.Handler):

  def emit(self, record):
    msg = self.format(record)
    if record.levelno >= logging.ERROR:
      utils.error(msg)
    elif record.levelno == logging.WARNING:
      utils.warn(msg)
    else:
      utils.puts(msg)


def _Run(cmd_or_args, dirname='.', local=False):
  if isinstance(cmd_or_args, list):
    cmd = ' '.join([pipes.quote(arg) for arg in cmd_or_args])
  else:
    cmd = cmd_or_args

  if local:
    with api.lcd(dirname):
      return api.local(cmd, capture=True)
  else:
    with api.cd(dirname):
      return api.run(cmd)


def _SetupTestHost():
  # work around current embedded image's lack of mktemp(1).
  wd = api.run('python -c "import tempfile; print tempfile.mkdtemp()"')
  with api.cd(wd):
    for script in ['timeout']:
      api.put(script, script, mode=0755)
  return wd


def _CleanupTestHost(dirname):
  api.run('rm -r {}'.format(pipes.quote(dirname)))
  network.disconnect_all()


def main():
  # Structured logging. Helps to pick up Paramiko (SSH transport layer) errors.
  root = logging.getLogger()
  root.setLevel(logging.INFO)
  root.addHandler(FabricLoggingHandler())

  o = options.Options(optspec)
  (opt, _, extra) = o.parse(sys.argv[1:])
  if extra:
    o.fatal('did not understand supplied extra arguments.')

  # Build a directory for the report to live in.
  report_name = 'wifi-{}-{:04}'.format(time.time(), opt.steps)
  if opt.journal:
    dest_dir = os.path.join(os.path.dirname(opt.journal), report_name)
  else:
    dest_dir = report_name

  if not os.path.exists(dest_dir):
    os.makedirs(dest_dir)

  logging.info('Report being written to %s', dest_dir)

  # we run diagnostics, write their output to files, and gather the files into
  # a report that we present at the end of the run.
  cache = collections.defaultdict(dict)
  local_run = functools.partial(_Run, local=True)

  # always gather network statistics for the system we're on
  system = platform.system()
  lifs = ifstats.InterfaceStats(system=system, runner=local_run)

  for host, output in api.execute(lifs.Gather).items():
    cache[host].update(output)
  lresults = ifstats.Parse(system, cache['<local-only>'])
  bssid = lresults.get('link', {}).get('BSSID')

  if opt.skid:
    logging.info('Getting stats from skid %s', opt.skid)
    try:
      status_wireless = ifstats_skids.GetStatusWireless(opt.skid)
      cache[opt.skid]['status_wireless'] = status_wireless
    except IOError as e:
      logging.warning('Got IOError while connecting to skid %s: %s',
                      opt.skid, e)

  if opt.remote:
    # update Fabric env for embedded systems
    api.env.update({
        'always_use_pty': False,
        'key_filename': os.path.expanduser('~/.ssh/bruno-sshkey'),
        'user': 'root',
        'shell': 'sh -l -c',
    })
    hosts = opt.remote.split(',')

    wd = api.execute(_SetupTestHost, hosts=hosts).values()[0]
    atexit.register(api.execute, _CleanupTestHost, wd, hosts=hosts)

    ifsystem = 'Linux'
    run = functools.partial(_Run, dirname=wd, local=False)

    # Gather network statistics from remote system
    ifs = ifstats.InterfaceStats(system=ifsystem, runner=run,
                                 interface=opt.interface)
    for host, output in api.execute(ifs.Gather, hosts=hosts).items():
      cache[host].update(output)

    # try to compute a bind address for iperf automatically.
    results = ifstats.Parse(system, cache[opt.remote])
    addr = results.get('addr', {}).get(opt.interface, '')
  else:
    ifsystem = system
    run = local_run
    hosts = []

    # try to compute a bind address for iperf automatically.
    addr = lresults.get('addr', {}).get(opt.interface, '')

  # because ip addr usually includes a subnet mask, which will prevent iperf
  # from binding to the address
  mask = addr.find('/')
  if mask > -1:
    addr = addr[:mask]

  if opt.monitor:
    defaults = {
        # on a modern MacBook, en0 is the AirPort and can both monitor and send
        'Darwin': 'en0',
        # on Linux, separate client and monitor interfaces are needed; and the
        # monitor interface must be manually created
        'Linux': 'moni0',  # from the `iw` documentation
    }

    if opt.monitor_interface:
      monif = opt.monitor_interface
    else:
      monif = defaults.get(system)

    if not monif:
      logging.error('Cannot gather tcpdump: no monitor interface specified '
                    'and autodetect failed.')

    tcpdump_proc, tcpdump_stderr = tcpdump.Tcpdump(monif, bssid, dest_dir,
                                                   opt.filter)
    logging.info('Gathering tcpdump in background as %d', tcpdump_proc.pid)

  if opt.bind and not addr:
    addr = opt.bind

  ips = iperf.Iperf(runner=run, bind=addr)

  # `iperf` returns 56 if it can't reach the server, or 57 if it doesn't receive
  # a final report from it on Linux; don't abort in these cases
  with api.settings(warn_only=True):
    for host, output in api.execute(ips.RunTestSeries, opt.destination,
                                    hosts=hosts).items():
      cache[host].update(output)

  # `isostream` won't end on its own, so we wrap it with `timeout` and accept a
  # return code of 124 (timed out) as well.
  with api.settings(ok_ret_codes=[0, 124]):
    for host, output in api.execute(isostream.RunIsostreamTest, run,
                                    opt.destination, time=opt.time,
                                    hosts=hosts).items():
      cache[host]['isostream'] = output

  if opt.monitor:
    try:
      tcpdump_proc.terminate()
    except OSError:
      subprocess.check_call(['sudo', 'kill', str(tcpdump_proc.pid)])

    tcpdump_stderr.flush()
    tcpdump_stderr.close()

  if opt.journal:
    with open(opt.journal, 'a') as journal:
      print >> journal, report_name

  # TODO(willangley): write out correctly if more than one host
  for host, items in cache.items():
    for name, value in items.items():
      with open(os.path.join(dest_dir, name), 'w+b') as outfile:
        outfile.write(value)


if __name__ == '__main__':
  main()

