"""Convenience functions for use by network tests or whomever.

This library is to release in the public repository.
"""

import commands, os, re, socket, sys, time, struct
from autotest_lib.client.common_lib import error
from autotest_lib.client.bin import utils as client_utils
import utils

TIMEOUT = 10 # Used for socket timeout and barrier timeout


class network_utils(object):
    def reset(self, ignore_status=False):
        utils.system('service network restart', ignore_status=ignore_status)


    def start(self, ignore_status=False):
        utils.system('service network start', ignore_status=ignore_status)


    def stop(self, ignore_status=False):
        utils.system('service network stop', ignore_status=ignore_status)


    def list(self):
        utils.system('/sbin/ifconfig -a')


    def get_ip_local(self, query_ip, netmask="24"):
        """
        Get ip address in local system which can communicate with query_ip.

        @param query_ip: IP of client which wants to communicate with
                autotest machine.
        @return: IP address which can communicate with query_ip
        """
        ip = client_utils.system_output("ip addr show to %s/%s" %
                                        (query_ip, netmask))
        ip = re.search(r"inet ([0-9.]*)/",ip)
        if ip is None:
            return ip
        return ip.group(1)


    def disable_ip_local_loopback(self, ignore_status=False):
        utils.system("echo '1' > /proc/sys/net/ipv4/route/no_local_loopback",
                     ignore_status=ignore_status)
        utils.system('echo 1 > /proc/sys/net/ipv4/route/flush',
                     ignore_status=ignore_status)


    def enable_ip_local_loopback(self, ignore_status=False):
        utils.system("echo '0' > /proc/sys/net/ipv4/route/no_local_loopback",
                     ignore_status=ignore_status)
        utils.system('echo 1 > /proc/sys/net/ipv4/route/flush',
                     ignore_status=ignore_status)


    def process_mpstat(self, mpstat_out, sample_count, loud = True):
        """Parses mpstat output of the following two forms:
        02:10:17     0    0.00    0.00    0.00    0.00    0.00    0.00   \
        0.00  100.00   1012.87
        02:10:13 PM    0    0.00    0.00    0.00    0.00    0.00    0.00 \
        0.00  100.00   1019.00
        """
        mpstat_keys = ['time', 'CPU', 'user', 'nice', 'sys', 'iowait', 'irq',
                       'soft', 'steal', 'idle', 'intr/s']
        if loud:
            print mpstat_out

        # Remove the optional AM/PM appearing in time format
        mpstat_out = mpstat_out.replace('AM', '')
        mpstat_out = mpstat_out.replace('PM', '')

        regex = re.compile('(\S+)')
        stats = []
        for line in mpstat_out.splitlines()[3:]:
            match = regex.findall(line)
            # Skip the "Average" computed by mpstat. We are gonna compute the
            # average ourself.  Pick only the aggregate 'all' CPU results
            if match and match[0] != 'Average:' and match[1] == 'all':
                stats.append(dict(zip(mpstat_keys, match)))

        if sample_count >= 5:
            # Throw away first and last sample
            stats = stats[1:-1]

        cpu_stats = {}
        for key in ['user', 'nice', 'sys', 'iowait', 'irq', 'soft', 'steal',
                    'idle', 'intr/s']:
            x = [float(row[key]) for row in stats]
            if len(x):
                count = len(x)
            else:
                print 'net_utils.network_utils.process_mpstat: count is 0!!!\n'
                count = 1
            cpu_stats[key] = sum(x) / count

        return cpu_stats


def network():
    try:
        from autotest_lib.client.bin.net import site_net_utils
        return site_net_utils.network_utils()
    except:
        return network_utils()


class network_interface(object):

    ENABLE, DISABLE = (True, False)

    def __init__(self, name):
        autodir = os.environ['AUTODIR']
        self.ethtool = 'ethtool'
        self._name = name
        self.was_down = self.is_down()
        self.orig_ipaddr = self.get_ipaddr()
        self.was_loopback_enabled = self.is_loopback_enabled()
        self._socket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
        self._socket.settimeout(TIMEOUT)
        self._socket.bind((name, raw_socket.ETH_P_ALL))


    def restore(self):
        self.set_ipaddr(self.orig_ipaddr)
        # TODO (msb): The additional conditional guard needs cleanup:
        #             Underlying driver should simply perform a noop
        #             for disabling loopback on an already-disabled device,
        #             instead of returning non-zero exit code.

        # To avoid sending a RST to the autoserv ssh connection
        # don't disable loopback until the IP address is restored.
        if not self.was_loopback_enabled and self.is_loopback_enabled():
            self.disable_loopback()
        if self.was_down:
            self.down()


    def get_name(self):
        return self._name


    def parse_ethtool(self, field, match, option='', next_field=''):
        output = utils.system_output('%s %s %s' % (self.ethtool,
                                                   option, self._name))
        if output:
            match = re.search('\n\s*%s:\s*(%s)%s' %
                              (field, match, next_field), output, re.S)
            if match:
                return match.group(1)

        return ''


    def get_stats(self):
        stats = {}
        stats_path = '/sys/class/net/%s/statistics/' % self._name
        for stat in os.listdir(stats_path):
            f = open(stats_path + stat, 'r')
            if f:
                stats[stat] = int(f.read())
                f.close()
        return stats


    def get_stats_diff(self, orig_stats):
        stats = self.get_stats()
        for stat in stats.keys():
            if stat in orig_stats:
                stats[stat] = stats[stat] - orig_stats[stat]
            else:
                stats[stat] = stats[stat]
        return stats


    def get_driver(self):
        driver_path = os.readlink('/sys/class/net/%s/device/driver' %
                                  self._name)
        return os.path.basename(driver_path)


    def get_carrier(self):
        f = open('/sys/class/net/%s/carrier' % self._name)
        if not f:
            return ''
        carrier = f.read().strip()
        f.close()
        return carrier


    def get_supported_link_modes(self):
        result = self.parse_ethtool('Supported link modes', '.*',
                                    next_field='Supports auto-negotiation')
        return result.split()


    def get_advertised_link_modes(self):
        result = self.parse_ethtool('Advertised link modes', '.*',
                                    next_field='Advertised auto-negotiation')
        return result.split()


    def is_autoneg_advertised(self):
        result = self.parse_ethtool('Advertised auto-negotiation',
                                        'Yes|No')
        return result == 'Yes'


    def get_speed(self):
        return int(self.parse_ethtool('Speed', '\d+'))


    def is_full_duplex(self):
        result = self.parse_ethtool('Duplex', 'Full|Half')
        return result == 'Full'


    def is_autoneg_on(self):
        result = self.parse_ethtool('Auto-negotiation', 'on|off')
        return result == 'on'


    def get_wakeon(self):
        return self.parse_ethtool('Wake-on', '\w+')


    def is_rx_summing_on(self):
        result = self.parse_ethtool('rx-checksumming', 'on|off', '-k')
        return result == 'on'


    def is_tx_summing_on(self):
        result = self.parse_ethtool('tx-checksumming', 'on|off', '-k')
        return result == 'on'


    def is_scatter_gather_on(self):
        result = self.parse_ethtool('scatter-gather', 'on|off', '-k')
        return result == 'on'


    def is_tso_on(self):
        result = self.parse_ethtool('tcp segmentation offload',
                                    'on|off', '-k')
        return result == 'on'


    def is_pause_autoneg_on(self):
        result = self.parse_ethtool('Autonegotiate', 'on|off', '-a')
        return result == 'on'


    def is_tx_pause_on(self):
        result = self.parse_ethtool('TX', 'on|off', '-a')
        return result == 'on'


    def is_rx_pause_on(self):
        result = self.parse_ethtool('RX', 'on|off', '-a')
        return result == 'on'


    def _set_loopback(self, mode, enable_disable):
        return utils.system('%s -L %s %s %s' %
                      (self.ethtool, self._name, mode, enable_disable),
                      ignore_status=True)


    def enable_loopback(self):
        # If bonded do not set loopback mode.
        # Try mac loopback first then phy loopback
        # If both fail, raise an error
        if bond().is_enabled():
            raise error.TestError('Unable to enable loopback while '
                                  'bonding is enabled.')
        if (self._set_loopback('phyint', 'enable') > 0 and
            self._set_loopback('mac', 'enable') > 0):
            raise error.TestError('Unable to enable loopback')
        # Add a 1 second wait for drivers which do not have
        # a synchronous loopback enable
        # TODO (msb); Remove this wait once the drivers are fixed
        if self.get_driver() in ['tg3', 'bnx2x']:
            time.sleep(1)
        self.wait_for_carrier(timeout=30)


    def disable_loopback(self):
        # Try mac loopback first then phy loopback
        # If both fail, raise an error
        if (self._set_loopback('phyint', 'disable') > 0 and
            self._set_loopback('mac', 'disable') > 0):
            raise error.TestError('Unable to disable loopback')


    def is_loopback_enabled(self):
        # Don't try ethtool -l on a bonded host
        if bond().is_enabled():
            return False
        output = utils.system_output('%s -l %s' % (self.ethtool, self._name))
        if output:
            return 'enabled' in output
        return False


    def enable_promisc(self):
        utils.system('ifconfig %s promisc' % self._name)


    def disable_promisc(self):
        utils.system('ifconfig %s -promisc' % self._name)


    def get_hwaddr(self):
        f = open('/sys/class/net/%s/address' % self._name)
        hwaddr = f.read().strip()
        f.close()
        return hwaddr


    def set_hwaddr(self, hwaddr):
        utils.system('ifconfig %s hw ether %s' % (self._name, hwaddr))


    def add_maddr(self, maddr):
        utils.system('ip maddr add %s dev %s' % (maddr, self._name))


    def del_maddr(self, maddr):
        utils.system('ip maddr del %s dev %s' % (maddr, self._name))


    def get_ipaddr(self):
        ipaddr = "0.0.0.0"
        output = utils.system_output('ifconfig %s' % self._name)
        if output:
            match = re.search("inet addr:([\d\.]+)", output)
            if match:
                ipaddr = match.group(1)
        return ipaddr


    def set_ipaddr(self, ipaddr):
        utils.system('ifconfig %s %s' % (self._name, ipaddr))


    def is_down(self):
        output = utils.system_output('ifconfig %s' % self._name)
        if output:
            return 'UP' not in output
        return False

    def up(self):
        utils.system('ifconfig %s up' % self._name)


    def down(self):
        utils.system('ifconfig %s down' % self._name)


    def wait_for_carrier(self, timeout=60):
        while timeout and self.get_carrier() != '1':
            timeout -= 1
            time.sleep(1)
        if timeout == 0:
            raise error.TestError('Timed out waiting for carrier.')


    def send(self, buf):
        self._socket.send(buf)


    def recv(self, len):
        return self._socket.recv(len)


    def flush(self):
        self._socket.close()
        self._socket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
        self._socket.settimeout(TIMEOUT)
        self._socket.bind((self._name, raw_socket.ETH_P_ALL))


def netif(name):
    try:
        from autotest_lib.client.bin.net import site_net_utils
        return site_net_utils.network_interface(name)
    except:
        return network_interface(name)


class bonding(object):
    """This class implements bonding interface abstraction."""

    NO_MODE = 0
    AB_MODE = 1
    AD_MODE = 2

    def is_enabled(self):
        raise error.TestError('Undefined')


    def is_bondable(self):
        raise error.TestError('Undefined')


    def enable(self):
        raise error.TestError('Undefined')


    def disable(self):
        raise error.TestError('Undefined')


    def get_mii_status(self):
        return {}


    def get_mode(self):
        return bonding.NO_MODE


    def wait_for_state_change(self):
        """Wait for bonding state change.

        Wait up to 90 seconds to successfully ping the gateway.
        This is to know when LACP state change has converged.
        (0 seconds is 3x lacp timeout, use by protocol)
        """

        netif('eth0').wait_for_carrier(timeout=60)
        wait_time = 0
        while wait_time < 100:
            time.sleep(10)
            if not utils.ping_default_gateway():
                return True
            wait_time += 10
        return False


    def get_active_interfaces(self):
        return []


    def get_slave_interfaces(self):
        return []


def bond():
    try:
        from autotest_lib.client.bin.net import site_net_utils
        return site_net_utils.bonding()
    except:
        return bonding()


class raw_socket(object):
    """This class implements an raw socket abstraction."""
    ETH_P_ALL = 0x0003 # Use for binding a RAW Socket to all protocols
    SOCKET_TIMEOUT = 1
    def __init__(self, iface_name):
        """Initialize an interface for use.

        Args:
          iface_name: 'eth0'  interface name ('eth0, eth1,...')
        """
        self._name = iface_name
        self._socket = None
        self._socket_timeout = raw_socket.SOCKET_TIMEOUT
        socket.setdefaulttimeout(self._socket_timeout)
        if self._name is None:
            raise error.TestError('Invalid interface name')


    def socket(self):
        return self._socket


    def socket_timeout(self):
        """Get the timeout use by recv_from"""
        return self._socket_timeout


    def set_socket_timeout(self, timeout):
        """Set the timeout use by recv_from.

        Args:
          timeout: time in seconds
        """
        self._socket_timeout = timeout

    def open(self, protocol=None):
        """Opens the raw socket to send and receive.

        Args:
          protocol : short in host byte order. None if ALL
        """
        if self._socket is not None:
            raise error.TestError('Raw socket already open')

        if protocol is None:
            self._socket = socket.socket(socket.PF_PACKET,
                                         socket.SOCK_RAW)

            self._socket.bind((self._name, self.ETH_P_ALL))
        else:
            self._socket = socket.socket(socket.PF_PACKET,
                                         socket.SOCK_RAW,
                                         socket.htons(protocol))
            self._socket.bind((self._name, self.ETH_P_ALL))

        self._socket.settimeout(1) # always running with 1 second timeout

    def close(self):
        """ Close the raw socket"""
        if self._socket is not None:
            self._socket.close()
            self._socket = None
        else:
            raise error.TestError('Raw socket not open')


    def recv(self, timeout):
        """Synchroneous receive.

        Receives one packet from the interface and returns its content
        in a string. Wait up to timeout for the packet if timeout is
        not 0. This function filters out all the packets that are
        less than the minimum ethernet packet size (60+crc).

        Args:
          timeout: max time in seconds to wait for the read to complete.
                   '0', wait for ever until a valid packet is received

        Returns:
          packet:    None no packet was received
                     a binary string containing the received packet.
          time_left: amount of time left in timeout
        """
        if self._socket is None:
            raise error.TestError('Raw socket not open')

        time_left = timeout
        packet = None
        while time_left or (timeout == 0):
            try:
                packet = self._socket.recv(ethernet.ETH_PACKET_MAX_SIZE)
                if len(packet) >= (ethernet.ETH_PACKET_MIN_SIZE-4):
                    break
                packet = None
                if timeout and time_left:
                    time_left -= raw_socket.SOCKET_TIMEOUT
            except socket.timeout:
                packet = None
                if timeout and time_left:
                    time_left -= raw_socket.SOCKET_TIMEOUT

        return packet, time_left


    def send(self, packet):
        """Send an ethernet packet."""
        if self._socket is None:
            raise error.TestError('Raw socket not open')

        self._socket.send(packet)


    def send_to(self, dst_mac, src_mac, protocol, payload):
        """Send an ethernet frame.

        Send an ethernet frame, formating the header.

        Args:
          dst_mac: 'byte string'
          src_mac: 'byte string'
          protocol: short in host byte order
          payload: 'byte string'
        """
        if self._socket is None:
            raise error.TestError('Raw socket not open')
        try:
            packet = ethernet.pack(dst_mac, src_mac, protocol, payload)
        except:
            raise error.TestError('Invalid Packet')
        self.send(packet)


    def recv_from(self, dst_mac, src_mac, protocol):
        """Receive an ethernet frame that matches the dst, src and proto.

        Filters all received packet to find a matching one, then unpack
        it and present it to the caller as a frame.

        Waits up to self._socket_timeout for a matching frame before
        returning.

        Args:
          dst_mac: 'byte string'. None do not use in filter.
          src_mac: 'byte string'. None do not use in filter.
          protocol: short in host byte order. None do not use in filter.

        Returns:
          ethernet frame: { 'dst' : byte string,
                            'src' : byte string,
                            'proto' : short in host byte order,
                            'payload' : byte string
                          }
        """
        start_time = time.clock()
        timeout = self._socket_timeout
        while 1:
            frame = None
            packet, timeout = self.recv(timeout)
            if packet is not None:
                frame = ethernet.unpack(packet)
                if ((src_mac is None or frame['src'] == src_mac) and
                    (dst_mac is None or frame['dst'] == dst_mac) and
                    (protocol is None or frame['proto'] == protocol)):
                    break;
                elif (timeout == 0 or
                      time.clock() - start_time > float(self._socket_timeout)):
                    frame = None
                    break
            else:
                if (timeout == 0 or
                    time.clock() - start_time > float(self._socket_timeout)):
                    frame = None
                    break
                continue

        return frame


class ethernet(object):
    """Provide ethernet packet manipulation methods."""
    HDR_LEN = 14     # frame header length
    CHECKSUM_LEN = 4 # frame checksum length

    # Ethernet payload types - http://standards.ieee.org/regauth/ethertype
    ETH_TYPE_IP        = 0x0800 # IP protocol
    ETH_TYPE_ARP       = 0x0806 # address resolution protocol
    ETH_TYPE_CDP       = 0x2000 # Cisco Discovery Protocol
    ETH_TYPE_8021Q     = 0x8100 # IEEE 802.1Q VLAN tagging
    ETH_TYPE_IP6       = 0x86DD # IPv6 protocol
    ETH_TYPE_LOOPBACK  = 0x9000 # used to test interfaces
    ETH_TYPE_LLDP      = 0x88CC # LLDP frame type

    ETH_PACKET_MAX_SIZE = 1518  # maximum ethernet frane size
    ETH_PACKET_MIN_SIZE = 64    # minimum ethernet frane size

    ETH_LLDP_DST_MAC = '01:80:C2:00:00:0E' # LLDP destination mac

    FRAME_KEY_DST_MAC = 'dst' # frame destination mac address
    FRAME_KEY_SRC_MAC = 'src' # frame source mac address
    FRAME_KEY_PROTO = 'proto' # frame protocol
    FRAME_KEY_PAYLOAD = 'payload' # frame payload


    def __init__(self):
        pass;


    @staticmethod
    def mac_string_to_binary(hwaddr):
        """Converts a MAC address text string to byte string.

        Converts a MAC text string from a text string 'aa:aa:aa:aa:aa:aa'
        to a byte string 'xxxxxxxxxxxx'

        Args:
          hwaddr: a text string containing the MAC address to convert.

        Returns:
          A byte string.
        """
        val = ''.join([chr(b) for b in [int(c, 16) \
                                        for c in hwaddr.split(':',6)]])
        return val


    @staticmethod
    def mac_binary_to_string(hwaddr):
        """Converts a MAC address byte string to text string.

        Converts a MAC byte string 'xxxxxxxxxxxx' to a text string
        'aa:aa:aa:aa:aa:aa'

        Args:
          hwaddr: a byte string containing the MAC address to convert.

        Returns:
         A text string.
        """
        return "%02x:%02x:%02x:%02x:%02x:%02x" % tuple(map(ord,hwaddr))


    @staticmethod
    def pack(dst, src, protocol, payload):
        """Pack a frame in a byte string.

        Args:
          dst: destination mac in byte string format
          src: src mac address in byte string format
          protocol: short in network byte order
          payload: byte string payload data

        Returns:
          An ethernet frame with header and payload in a byte string.
        """
        # numbers are converted to network byte order (!)
        frame = struct.pack("!6s6sH", dst, src, protocol) + payload
        return frame


    @staticmethod
    def unpack(raw_frame):
        """Unpack a raw ethernet frame.

        Returns:
          None on error
            { 'dst' : byte string,
              'src' : byte string,
              'proto' : short in host byte order,
              'payload' : byte string
            }
        """
        packet_len = len(raw_frame)
        if packet_len < ethernet.HDR_LEN:
            return None

        payload_len = packet_len - ethernet.HDR_LEN
        frame = {}
        frame[ethernet.FRAME_KEY_DST_MAC], \
        frame[ethernet.FRAME_KEY_SRC_MAC], \
        frame[ethernet.FRAME_KEY_PROTO] = \
            struct.unpack("!6s6sH", raw_frame[:ethernet.HDR_LEN])
        frame[ethernet.FRAME_KEY_PAYLOAD] = \
            raw_frame[ethernet.HDR_LEN:ethernet.HDR_LEN+payload_len]
        return frame


def ethernet_packet():
    try:
        from autotest_lib.client.bin.net import site_net_utils
        return site_net_utils.ethernet()
    except:
        return ethernet()
