# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


import optparse
import pickle
import re
import subprocess

import common
from autotest_lib.client.cros.cellular import cellular
from autotest_lib.client.cros.cellular import cellular_logging
from autotest_lib.client.cros.cellular import labconfig_data

log = cellular_logging.SetupCellularLogging('labconfig')


class LabConfigError(Exception):
    """Exception thrown on bad lab configuration"""
    pass


def get_interface_ip(interface='eth0'):
    """Returns the IP address for an interface, or None if not found.
    @param interface: the interface to request IP address for.
    """

    # We'd like to use
    #  utils.system_output('ifconfig eth0 2>&1', retain_output=True)
    # but that gives us a dependency on the rest of autotest, which
    # means that running the unit test requires pythonpath manipulation
    stdout = subprocess.Popen(['ip', '-4', 'addr', 'show', 'dev', interface],
                              stdout=subprocess.PIPE).communicate()[0]

    match = re.search(r'inet ([0-9.]+)[/ ]', stdout)
    if not match:
        return None
    return match.group(1)


class Configuration(object):
    """Configuration for a cellular test.

    This includes things like the address of the cell emulator device
    and details of the RF switching between the emulated basestation
    and the DUT."""

    def __init__(self, args):
        # For server tests, this constructor runs as part of the
        # server control file, on whatever machine the test was
        # started on.
        parser = optparse.OptionParser()

        # Record our args so we can serialize ourself.
        self.args = args

        self.ip = None

        parser.add_option('--cell', dest='cell', default=None,
                          help='Cellular test cell to use')
        parser.add_option(
            '--technology', dest='technology', default='all',
            help='Radio access technologies to use (e.g. "WCDMA")')
        (self.options, _) = parser.parse_args(args)

        self.cell = self._get_cell(self.options.cell)

    def _get_cell(self, name):
        """Extracts the named cell from labconfig_data.CELLS."""
        if not name:
            raise LabConfigError(
                'Could not find --cell argument.  ' +
                'To specify a cell, pass --args=--cell=foo to run_remote_tests')

        if name not in labconfig_data.CELLS:
            raise LabConfigError(
                'Could not find cell %s, valid cells are %s' % (
                    name, labconfig_data.CELLS.keys()))

        return labconfig_data.CELLS[name]

    def _get_dut(self, machine=None):
        """Returns the DUT record for machine from cell["duts"]
        Args:
            machine:  name or IP of machine.  None: for "the current machine".

        Right now, we use the interface of eth0 to figure out which
        machine we're running on.  The important thing is that this
        matches the IP address in the cell duts configuration.  We'll
        have to come up with a better way if this proves brittle."""

        # TODO(byronk) : crosbug.com/235911:
        # autotest: Getting IP address from eth0 by name is brittle
        if self.ip and not machine:
            machine = self.ip
        ifconfig = ''
        if not machine:
            log.debug('self.ip is : %s ' % self.ip)
            # TODO(byronk): use sysfs to find network interface
            possible_interfaces = ['eth0', 'eth1', 'eth_test']
            log.debug('Looking for an up network interface in : %s' %
                      possible_interfaces)
            for interface in possible_interfaces:
                machine = get_interface_ip(interface)
                if machine:
                    log.debug('Got an IP address: %s Stopping the search.. ' %
                              machine)
                    self.ip = machine
                    break
            else:
                ifconfig = subprocess.Popen(['ip', 'addr', 'show'],
                        stdout=subprocess.PIPE).communicate()[0]
        if not machine:
            raise LabConfigError(
                'Could not determine which machine we are.\n'
                '  Cell =  %s \n' % self.options.cell +
                'Tried these interface names: %s \n' % possible_interfaces +
                '`ip addr show` output:\n%s' % ifconfig
            )

        for dut in self.cell["duts"]:
            if machine == dut["address"] or machine == dut["name"]:
                return dut

        raise LabConfigError(
            'This machine %s not matching: (%s,%s) in config. Cell = %s: %s' %
            (machine, dut['address'],
             dut['name'], self.options.cell, self.cell['duts']))

    def get_technologies(self, machine=None):
        """Gets technologies to use for machine; defaults to all available.
        @param machine: Machine to get technologies for.
        """
        technologies_list = self.options.technology.split(',')

        if 'all' in technologies_list:
            m = self._get_dut(machine)
            technologies_list = m["technologies"]

        enums = [getattr(cellular.Technology, t, None)
                 for t in technologies_list]

        if None in enums:
            raise LabConfigError(
                'Could not understand a technology in %s' % technologies_list)

        return enums

    def get_rf_switch_port(self, machine=None):
        """Get the RF Switch Port for the specified machine.
        @param machine: machine to get rf switch port for
        """
        dut = self._get_dut(machine)
        print dut
        return dut['rf_switch_port']

    def get_pickle(self):
        """Get pickled object."""
        return pickle.dumps(self)
