#!/usr/bin/python

"""Models wired and wireless interfaces."""

import logging
import os
import re
import subprocess

# This has to be called before another module calls it with a higher log level.
# pylint: disable=g-import-not-at-top
logging.basicConfig(level=logging.DEBUG)

import experiment
import wpactrl

METRIC_5GHZ = 20
METRIC_24GHZ_5GHZ = 21
METRIC_24GHZ = 22
METRIC_TEMPORARY_CONNECTION_CHECK = 99

RFC2385_MULTICAST_ROUTE = '239.0.0.0/8'

experiment.register('WifiSimulateWireless')
CWMP_PATH = '/tmp/cwmp'
MAX_ACS_FAILURE_S = 60


class Interface(object):
  """Represents an interface.

  Base class for more specific interface types.
  """

  CONNECTION_CHECK = 'connection_check'
  IP_ROUTE = ['ip', 'route']
  IP_ADDR_SHOW = ['ip', 'addr', 'show', 'dev']

  def __init__(self, name, base_metric):
    self.name = name

    # Currently connected links for this interface, e.g. ethernet.
    self.links = set()

    # Whether [ACS, internet] access is currently available via this interface.
    self._has_acs = None
    self._has_internet = None

    self._subnet = None
    self._gateway_ip = None
    self.base_metric = base_metric
    self.metric_offset = 0

    # Until this is set True, the routing table will not be touched.
    self._initialized = False

  @property
  def metric(self):
    return str(int(self.base_metric) + self.metric_offset)

  def _connection_check(self, check_acs):
    """Check this interface's connection status.

    Args:
      check_acs:  If true, check for ACS access rather than internet access.

    Returns:
      Whether the connection is working.
    """
    # Until initialized, we want to act as if the interface is down.
    if not self._initialized:
      logging.info('%s not initialized; not running connection_check%s',
                   self.name, ' (ACS)' if check_acs else '')
      return None

    if not self.links:
      logging.info('Connection check for %s failed due to no links', self.name)
      return False

    logging.debug('Gateway IP for %s is %s', self.name, self._gateway_ip)
    if self._gateway_ip is None:
      logging.info('Connection check%s for %s failed due to no gateway IP',
                   ' (ACS)' if check_acs else '', self.name)
      return False

    # Temporarily add a route to make sure the connection check can be run.
    # Give it a high metric so that it won't interfere with normal default
    # routes.
    added_temporary_route = False
    if 'default' not in self.current_routes():
      logging.debug('Adding temporary connection check routes for dev %s',
                    self.name)
      self._ip_route('add', self._gateway_ip,
                     'dev', self.name,
                     'metric', str(METRIC_TEMPORARY_CONNECTION_CHECK))
      self._ip_route('add', 'default',
                     'via', self._gateway_ip,
                     'dev', self.name,
                     'metric', str(METRIC_TEMPORARY_CONNECTION_CHECK))
      added_temporary_route = True

    cmd = [self.CONNECTION_CHECK, '-I', self.name]
    if check_acs:
      cmd.append('-a')

    with open(os.devnull, 'w') as devnull:
      result = subprocess.call(cmd, stdout=devnull, stderr=devnull) == 0
      logging.info('Connection check%s for %s %s',
                   ' (ACS)' if check_acs else '',
                   self.name,
                   'passed' if result else 'failed')

    # Delete the temporary route.
    if added_temporary_route:
      logging.debug('Deleting temporary connection check routes for dev %s',
                    self.name)
      self._ip_route('del', 'default',
                     'dev', self.name,
                     'metric', str(METRIC_TEMPORARY_CONNECTION_CHECK))
      self._ip_route('del', self._gateway_ip,
                     'dev', self.name,
                     'metric', str(METRIC_TEMPORARY_CONNECTION_CHECK))

    return result

  def gateway(self):
    return self._gateway_ip

  def acs(self):
    if self._has_acs is None:
      self._has_acs = self._connection_check(check_acs=True)

    return self._has_acs

  def internet(self):
    if self._has_internet is None:
      self._has_internet = self._connection_check(check_acs=False)

    return self._has_internet

  def add_routes(self):
    """Update default routes for this interface.

    Remove any stale routes and add any missing desired routes.
    """
    if self.metric is None:
      logging.info('Cannot add route for %s without a metric.', self.name)
      return

    if self._gateway_ip is None:
      logging.info('Cannot add route for %s without a gateway IP.', self.name)
      return

    # If the current routes are the same, there is nothing to do.  If either
    # exists but is different, delete it before adding an updated one.
    current = self.current_routes()
    default = current.get('default', {})
    if ((default.get('via', None), default.get('metric', None)) !=
        (self._gateway_ip, str(self.metric))):
      logging.debug('Adding default route for dev %s', self.name)
      self.delete_route('default')
      self._ip_route('add', 'default',
                     'via', self._gateway_ip,
                     'dev', self.name,
                     'metric', str(self.metric))

    subnet = current.get('subnet', {})
    if (self._subnet and
        (subnet.get('route', None), subnet.get('metric', None)) !=
        (self._subnet, str(self.metric))):
      logging.debug('Adding subnet route for dev %s', self.name)
      self.delete_route('subnet')
      self._ip_route('add', self._subnet,
                     'dev', self.name,
                     'metric', str(self.metric))

    # RFC2365 multicast route.
    if current.get('multicast', {}).get('metric', None) != str(self.metric):
      logging.debug('Adding multicast route for dev %s', self.name)
      self.delete_route('multicast')
      self._ip_route('add', RFC2385_MULTICAST_ROUTE,
                     'dev', self.name,
                     'metric', str(self.metric))

  def delete_route(self, *args):
    """Delete default and/or subnet routes for this interface.

    Args:
      *args:  Which routes to delete.  Must be at least one of 'default',
          'subnet', 'multicast'.

    Raises:
      ValueError:  If neither default nor subnet is True.
    """
    args = set(args)
    args &= set(('default', 'subnet', 'multicast'))
    if not args:
      raise ValueError(
          'Must specify at least one of default, subnet, multicast to delete.')

    for route_type in args:
      while route_type in self.current_routes():
        logging.debug('Deleting %s route for dev %s', route_type, self.name)
        self._ip_route('del', self.current_routes()[route_type]['route'],
                       'dev', self.name)

  def current_routes(self):
    """Read the current routes for this interface.

    Returns:
      A dict mapping 'default' and/or 'subnet' to a dict containing the gateway
      [and metric] of the route.  Only contains keys for routes that are
      present.
    """
    result = {}
    for line in self._ip_route().splitlines():
      if 'dev %s' % self.name in line:
        if line.startswith('default'):
          route_type = 'default'
        elif re.search(r'/\d{1,2}$', line.split()[0]):
          route_type = 'subnet'
        else:
          continue
        route = {}
        key = 'route'
        for token in line.split():
          if token in ['via', 'metric']:
            key = token
          elif key:
            if key == 'route' and token == RFC2385_MULTICAST_ROUTE:
              route_type = 'multicast'
            route[key] = token
            key = None
        if route:
          result[route_type] = route

    return result

  def _ip_route(self, *args):
    if not self._initialized:
      logging.info('Not initialized, not running %s %s',
                   ' '.join(self.IP_ROUTE), ' '.join(args))
      return ''

    return self._really_ip_route(*args)

  def _really_ip_route(self, *args):
    try:
      logging.debug('%s calling ip route %s', self.name, ' '.join(args))
      return subprocess.check_output(self.IP_ROUTE + list(args))
    except subprocess.CalledProcessError as e:
      logging.error('Failed to call "ip route" with args %r: %s', args,
                    e.message)
      return ''

  def _ip_addr_show(self):
    try:
      return subprocess.check_output(self.IP_ADDR_SHOW + [self.name])
    except subprocess.CalledProcessError as e:
      logging.error('Could not get IP address for %s: %s', self.name, e.message)
      return None

  def get_ip_address(self):
    match = re.search(r'^\s*inet (?P<IP>\d+\.\d+\.\d+\.\d+)',
                      self._ip_addr_show(), re.MULTILINE)
    return match and match.group('IP') or None

  def set_gateway_ip(self, gateway_ip):
    logging.info('New gateway IP %s for %s', gateway_ip, self.name)
    self._gateway_ip = gateway_ip
    self.update_routes(expire_cache=True)

  def set_subnet(self, subnet):
    logging.info('New subnet %s for %s', subnet, self.name)
    self._subnet = subnet
    self.update_routes(expire_cache=True)

  def _set_link_status(self, link, is_up):
    """Set whether a link is up or not."""
    if is_up == (link in self.links):
      return

    had_links = bool(self.links)

    if is_up:
      logging.info('%s gained link %s', self.name, link)
      self.links.add(link)
    else:
      logging.info('%s lost link %s', self.name, link)
      self.links.remove(link)

    # If a link goes away, we may have lost access to something but not gained
    # it, and vice versa.
    if is_up != self._has_acs:
      self._has_acs = None

    if is_up != self._has_internet:
      self._has_internet = None

    if had_links != bool(self.links):
      self.update_routes(expire_cache=False)

  def expire_connection_status_cache(self):
    logging.debug('Expiring connection status cache for %s', self.name)
    self._has_internet = self._has_acs = None

  def update_routes(self, expire_cache=True):
    """Update this interface's routes.

    If the interface has ACS or internet access, prioritize its routes.  If it
    doesn't but has a link, deprioritize the routes.  If it has no links, delete
    the routes.

    Args:
      expire_cache:  If true, force a recheck of connection status before
      deciding how to prioritize routes.
    """
    logging.debug('Updating routes for %s', self.name)
    if expire_cache:
      self.expire_connection_status_cache()

    if self.acs() or self.internet():
      self.prioritize_routes()
    else:
      # If we still have a link, just deprioritize the routes, in case we're
      # wrong about the connection check.  If there's no actual link, then
      # really delete the routes.
      if self.links:
        self.deprioritize_routes()
      else:
        self.delete_route('default', 'subnet', 'multicast')

  def prioritize_routes(self):
    """When connection check succeeds, route priority (metric) should be normal.

    This is the inverse of deprioritize_routes.
    """
    if not self._initialized:
      return
    logging.info('%s routes have normal priority', self.name)
    self.metric_offset = 0
    self.add_routes()

  def deprioritize_routes(self):
    """When connection check fails, deprioritize routes by increasing metric.

    This is conservative alternative to deleting routes, in case we are mistaken
    about route not providing a useful connection.
    """
    if not self._initialized:
      return
    logging.info('%s routes have low priority', self.name)
    self.metric_offset = 50
    self.add_routes()

  def initialize(self):
    """Tell the interface it has its initial state.

    Until this is called, the interface won't run connection checks or touch the
    routing table.
    """
    self._initialized = True
    self.update_routes()


class Bridge(Interface):
  """Represents the wired bridge."""

  def __init__(self, *args, **kwargs):
    self._acs_autoprovisioning_filepath = kwargs.pop(
        'acs_autoprovisioning_filepath')
    super(Bridge, self).__init__(*args, **kwargs)
    self._moca_stations = set()

  @property
  def moca(self):
    return bool(self._moca_stations)

  @moca.setter
  def moca(self, is_up):
    self._set_link_status('moca', is_up)

  @property
  def ethernet(self):
    return 'ethernet' in self.links

  @ethernet.setter
  def ethernet(self, is_up):
    self._set_link_status('ethernet', is_up)

  def add_moca_station(self, node_id):
    if node_id not in self._moca_stations:
      self._moca_stations.add(node_id)
      self.moca = True

  def remove_moca_station(self, node_id):
    if node_id in self._moca_stations:
      self._moca_stations.remove(node_id)
      self.moca = bool(self._moca_stations)

  def prioritize_routes(self):
    """We only want ACS autoprovisioning when we're using a wired route."""
    super(Bridge, self).prioritize_routes()
    open(self._acs_autoprovisioning_filepath, 'w')

  def deprioritize_routes(self, *args, **kwargs):
    """We only want ACS autoprovisioning when we're using a wired route."""
    if os.path.exists(self._acs_autoprovisioning_filepath):
      os.unlink(self._acs_autoprovisioning_filepath)
    super(Bridge, self).deprioritize_routes(*args, **kwargs)

  def delete_route(self, *args, **kwargs):
    """We only want ACS autoprovisioning when we're using a wired route."""
    if os.path.exists(self._acs_autoprovisioning_filepath):
      os.unlink(self._acs_autoprovisioning_filepath)
    super(Bridge, self).delete_route(*args, **kwargs)

  def _connection_check(self, check_acs):
    """Support for WifiSimulateWireless."""
    failure_s = self._acs_session_failure_s()
    if (experiment.enabled('WifiSimulateWireless')
        and failure_s < MAX_ACS_FAILURE_S):
      logging.info('WifiSimulateWireless: failing bridge connection check%s '
                   '(no ACS contact for %d seconds, max %d seconds)',
                   ' (ACS)' if check_acs else '', failure_s, MAX_ACS_FAILURE_S)
      return False

    return super(Bridge, self)._connection_check(check_acs)

  def _acs_session_failure_s(self):
    """How long have we been failing to connect to the ACS?

    Returns:
      The number of seconds between the last attempted ACS session and the last
      successful ACS session.
    """
    contact = os.path.join(CWMP_PATH, 'acscontact')
    connected = os.path.join(CWMP_PATH, 'acsconnected')

    if not os.path.exists(contact) or not os.path.exists(connected):
      return 0

    return os.stat(contact).st_mtime - os.stat(connected).st_mtime


class Wifi(Interface):
  """Represents a wireless interface."""

  WPA_EVENT_RE = re.compile(r'<\d+>CTRL-EVENT-(?P<event>[A-Z\-]+).*')
  # pylint: disable=invalid-name
  WPACtrl = wpactrl.WPACtrl

  def __init__(self, *args, **kwargs):
    self.bands = kwargs.pop('bands', [])
    super(Wifi, self).__init__(*args, **kwargs)
    self._wpa_control = None
    self.initial_ssid = None

  @property
  def wpa_supplicant(self):
    return 'wpa_supplicant' in self.links

  @wpa_supplicant.setter
  def wpa_supplicant(self, is_up):
    self._set_link_status('wpa_supplicant', is_up)

  def attached(self):
    return self._wpa_control and self._wpa_control.attached

  def attach_wpa_control(self, path):
    """Attach to the wpa_supplicant control interface.

    Args:
      path:  The path containing the wpa_supplicant control interface socket.

    Returns:
      Whether attaching was successful.
    """
    if self.attached():
      return True

    socket = os.path.join(path, self.name)
    logging.debug('%s socket is %s', self.name, socket)
    try:
      self._wpa_control = self.get_wpa_control(socket)
      self._wpa_control.attach()
      logging.debug('%s successfully attached', self.name)
    except wpactrl.error as e:
      logging.error('Error attaching to wpa_supplicant: %s', e)
      return False

    status = self.wpa_status()
    logging.debug('%s status after attaching is %s', self.name, status)
    self.wpa_supplicant = status.get('wpa_state') == 'COMPLETED'
    if not self._initialized:
      self.initial_ssid = status.get('ssid')

    return True

  def wpa_status(self):
    """Parse the STATUS response from the wpa_supplicant control interface.

    Returns:
      A dict containing the parsed results, where key and value are separated by
      '=' on each line.
    """
    status = {}

    if self._wpa_control and self._wpa_control.attached:
      logging.debug('%s ctrl_iface_path %s',
                    self, self._wpa_control.ctrl_iface_path)
      lines = []
      try:
        lines = self._wpa_control.request('STATUS').splitlines()
      except wpactrl.error as e:
        logging.error('wpa_control STATUS request failed %s args %s',
                      e.message, e.args)
      for line in lines:
        if '=' not in line:
          continue
        k, v = line.strip().split('=', 1)
        status[k] = v

    logging.debug('%s wpa status is %s', self.name, status)
    return status

  def get_wpa_control(self, socket):
    return self.WPACtrl(socket)

  def detach_wpa_control(self):
    if self.attached():
      try:
        self._wpa_control.detach()
      except wpactrl.error:
        logging.error('Failed to detach from wpa_supplicant interface. This '
                      'may mean something else killed wpa_supplicant.')
        self._wpa_control = None

      self.wpa_supplicant = False

  def handle_wpa_events(self):
    if not self.attached():
      self.wpa_supplicant = False
      return

    while self._wpa_control.pending():
      match = self.WPA_EVENT_RE.match(self._wpa_control.recv())
      if match:
        event = match.group('event')
        if event == 'CONNECTED':
          self.wpa_supplicant = True
        elif event in ('DISCONNECTED', 'TERMINATING', 'ASSOC-REJECT',
                       'SSID-TEMP-DISABLED', 'AUTH-REJECT'):
          self.wpa_supplicant = False
          if event == 'TERMINATING':
            self.detach_wpa_control()
            break

        self.update_routes()

  def initialize(self):
    """Unset self.initial_ssid, which is only relevant during initialization."""

    self.initial_ssid = None
    super(Wifi, self).initialize()


class FrenzyWPACtrl(object):
  """A WPACtrl for Frenzy devices.

  Implements the same functions used on the normal WPACtrl, using a combination
  of the QCSAPI and wifi_files.  Keeps state in order to generate events by
  diffing saved state with current system state.
  """

  WIFIINFO_PATH = '/tmp/wifi/wifiinfo'

  def __init__(self, socket):
    self.ctrl_iface_path, self._interface = os.path.split(socket)

    # State from QCSAPI and wifi_files.
    self._client_mode = False
    self._ssid = None
    self._status = None
    self._security = None

    self._events = []

  def _qcsapi(self, *command):
    try:
      return subprocess.check_output(['qcsapi'] + list(command)).strip()
    except subprocess.CalledProcessError as e:
      logging.error('QCSAPI call failed: %s: %s', e, e.output)
      raise

  def attach(self):
    self._update()

  @property
  def attached(self):
    return self._client_mode

  def detach(self):
    raise wpactrl.error('Real WPACtrl always raises this when detaching.')

  def pending(self):
    self._update()
    return bool(self._events)

  def _update(self):
    """Generate and cache events, update state."""
    try:
      client_mode = self._qcsapi('get_mode', 'wifi0') == 'Station'
      ssid = self._qcsapi('get_ssid', 'wifi0')
      status = self._qcsapi('get_status', 'wifi0')
      security = (self._qcsapi('ssid_get_authentication_mode', 'wifi0', ssid)
                  if ssid else None)
    except subprocess.CalledProcessError:
      # If QCSAPI failed, skip update.
      return

    # If we have an SSID and are in client mode, and at least one of those is
    # new, then we have just connected.
    if client_mode and ssid and (not self._client_mode or ssid != self._ssid):
      self._events.append('<2>CTRL-EVENT-CONNECTED')

    # If we are in client mode but lost SSID, we disconnected.
    if client_mode and self._ssid and not ssid:
      self._events.append('<2>CTRL-EVENT-DISCONNECTED')

    # If there is an auth/assoc failure, then status (above) is 'Error'.  We
    # really want the converse of this implication (i.e. that 'Error' implies an
    # auth/assoc failure), but due to limited documentation this will have to
    # do.  It should be good enough:  if something else causes get_status to
    # return 'Error', we are probably not connected, and we don't do anything
    # special with auth/assoc failures specifically.
    if client_mode and status == 'Error' and self._status != 'Error':
      self._events.append('<2>CTRL-EVENT-SSID-TEMP-DISABLED')

    # If we left client mode, wpa_supplicant has terminated.
    if self._client_mode and not client_mode:
      self._events.append('<2>CTRL-EVENT-TERMINATING')

    self._client_mode = client_mode
    self._ssid = ssid
    self._status = status
    self._security = security

  def recv(self):
    return self._events.pop(0)

  def request(self, request_type):
    """Partial implementation of WPACtrl.request."""

    if request_type != 'STATUS':
      return ''

    self._update()

    if not self._client_mode or not self._ssid:
      return ''

    return ('wpa_state=COMPLETED\nssid=%s\nkey_mgmt=%s' %
            (self._ssid, self._security or 'NONE'))


class FrenzyWifi(Wifi):
  """Represents a Frenzy wireless interface."""

  # pylint: disable=invalid-name
  WPACtrl = FrenzyWPACtrl
