#!/usr/bin/python -S

"""Utils related to automatic channel selection."""

import random
import subprocess
import time

import utils


MODES = {
    '24MAIN_20': '2412 2432 2462',
    '24MAIN_40': '2412',
    '24MAIN_80': '',
    '24OVERLAP_20': '2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462',
    '24OVERLAP_40': '2412',
    '24OVERLAP_80': '',
    '5LOW_20': '5180 5200 5220 5240',
    '5LOW_40': '5180 5220',
    '5LOW_80': '5180',
    '5HIGH_20': '5745 5765 5785 5805 5825',
    '5HIGH_40': '5745 5785',
    '5HIGH_80': '5745',
    '5DFS_20': '5260 5280 5300 5320 5500 5520 5540 5560 5580 5660 5680 5700',
    '5DFS_40': '5260 5300 5500 5540 5660',
    '5DFS_80': '5260 5500',
}


def get_permitted_frequencies(band, autotype, width):
  try:
    return {
        ('2.4', 'LOW', '20'): MODES['24MAIN_20'],
        ('2.4', 'LOW', '40'): MODES['24MAIN_40'],
        ('2.4', 'HIGH', '20'): MODES['24MAIN_20'],
        ('2.4', 'HIGH', '40'): MODES['24MAIN_40'],
        ('2.4', 'NONDFS', '20'): MODES['24MAIN_20'],
        ('2.4', 'NONDFS', '40'): MODES['24MAIN_40'],
        ('2.4', 'ANY', '20'): MODES['24MAIN_20'],
        ('2.4', 'ANY', '40'): MODES['24MAIN_40'],
        ('2.4', 'OVERLAP', '20'): MODES['24OVERLAP_20'],
        ('2.4', 'OVERLAP', '40'): MODES['24OVERLAP_40'],
        ('5', 'LOW', '20'): MODES['5LOW_20'],
        ('5', 'LOW', '40'): MODES['5LOW_40'],
        ('5', 'LOW', '80'): MODES['5LOW_80'],
        ('5', 'HIGH', '20'): MODES['5HIGH_20'],
        ('5', 'HIGH', '40'): MODES['5HIGH_40'],
        ('5', 'HIGH', '80'): MODES['5HIGH_80'],
        ('5', 'DFS', '20'): MODES['5DFS_20'],
        ('5', 'DFS', '40'): MODES['5DFS_40'],
        ('5', 'DFS', '80'): MODES['5DFS_80'],
        ('5', 'NONDFS', '20'): ' '.join((MODES['5LOW_20'], MODES['5HIGH_20'])),
        ('5', 'NONDFS', '40'): ' '.join((MODES['5LOW_40'], MODES['5HIGH_40'])),
        ('5', 'NONDFS', '80'): ' '.join((MODES['5LOW_80'], MODES['5HIGH_80'])),
        ('5', 'ANY', '20'): ' '.join((MODES['5LOW_20'], MODES['5HIGH_20'],
                                      MODES['5DFS_20'])),
        ('5', 'ANY', '40'): ' '.join((MODES['5LOW_40'], MODES['5HIGH_40'],
                                      MODES['5DFS_40'])),
        ('5', 'ANY', '80'): ' '.join((MODES['5LOW_80'], MODES['5HIGH_80'],
                                      MODES['5DFS_80'])),
    }[(band, autotype, width)]
  except KeyError:
    raise ValueError('Unknown autochannel type: band=%s autotype=%s width=%s'
                     % (band, autotype, width))


def get_all_frequencies(band):
  """Get all 802.11 frequencies for the given band."""
  return get_permitted_frequencies(band, 'OVERLAP' if band == '2.4' else 'ANY',
                                   '20').split()


def scan(interface, band, autotype, width):
  """Do an autochannel scan and return the recommended channel.

  Args:
    interface: The interface on which to scan.
    band: The band on which to scan.
    autotype: Determines permitted frequencies.  See get_permitted_frequencies
      for valid values.
    width: Determines permitted frequencies.  See get_permitted_frequencies for
      valid values.

  Returns:
    The channel to use, or None if no recommendation can be made.
  """
  utils.log('Doing autochannel scan.')

  permitted_frequencies = get_permitted_frequencies(band, autotype, width)

  subprocess.call(('ip', 'link', 'set', interface, 'up'))

  # TODO(apenwarr): We really want to clear any old survey results first.  But
  # there seems to be no iw command for that yet...
  #
  # TODO(apenwarr): This only scans each channel for 100ms.  Ideally it should
  # scan for longer, to get a better activity sample.  It would also be nice to
  # continue scanning in the background while hostapd is running, using 'iw
  # offchannel'.  Retry this a few times if it fails, just in case there was a
  # scan already in progress started somewhere else (e.g. from waveguide).
  for _ in xrange(9):
    if utils.subprocess_quiet(('iw', 'dev', interface, 'scan', 'passive'),
                              no_stdout=True) == 0:
      break
    time.sleep(0.5)

  # TODO(apenwarr): This algorithm doesn't deal with overlapping channels. Just
  # because channel 1 looks good doesn't mean we should use it; activity in
  # overlapping channels could destroy performance.  In fact, overlapping
  # channel activity is much worse than activity on the main channel.  Also, if
  # using 40 MHz or 80 MHz channel width, we should count activity in all the 20
  # MHz sub-channels separately, and choose the least-active sub-channel as the
  # primary.
  best_frequency = best_noise = best_ratio = frequency = None
  for tokens in utils.subprocess_line_tokens(
      ('iw', 'dev', interface, 'survey', 'dump')):
    # TODO(apenwarr): Randomize the order of channels.  Otherwise when channels
    # are all about equally good, we would always choose exactly the same
    # channel, which might be bad in the case of hidden nodes.
    if len(tokens) >= 2 and tokens[0] == 'frequency:':
      frequency = tokens[1]
      noise = active = busy = None
    elif len(tokens) >= 2 and tokens[0] == 'noise:':
      noise = int(tokens[1])
    elif len(tokens) >= 4 and tokens[:3] == ('channel', 'active', 'time:'):
      active = int(tokens[3])
    elif len(tokens) >= 4 and tokens[:3] == ('channel', 'receive', 'time:'):
      busy = int(tokens[3])
      # TODO(rofrankel): busy or 1 might make more sense than busy + 1 here;
      # need to discuss with apenwarr@.
      ratio = (active + 1) * 1000 / (busy + 1)

      if frequency not in permitted_frequencies.split():
        continue

      # Some radios support both bands, but we only want to match channels on
      # the band we have chosen.
      if band[0] != frequency[0]:
        continue

      utils.log('freq=%s ratio=%s noise=%s', frequency, ratio, noise)

      if best_noise is None or best_noise - 15 > noise or best_ratio < ratio:
        best_frequency, best_ratio, best_noise = frequency, ratio, noise

  if not best_frequency:
    utils.log('Autoscan did not find any channel, picking random channel.')
    utils.log('Permitted frequencies: %s', permitted_frequencies)
    if not permitted_frequencies:
      utils.log('No default channel: type=%s band=%s width=%s',
                autotype, band, width)
      return None
    best_frequency = random.choice(permitted_frequencies.split())

  utils.log('autofreq=%s', best_frequency)

  for tokens in utils.subprocess_line_tokens(('iw', 'phy')):
    if len(tokens) >= 4 and tokens[2] == 'MHz':
      frequency = tokens[1]
      if frequency == best_frequency:
        channel = tokens[3].strip('[]')
        break

  if not channel:
    utils.log('No channel number matched freq=%s.', best_frequency)
    return None

  utils.log('autochannel=%s', channel)

  return channel
