#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.

"""This class defines devices.

   This file defines the base class of all devices,
   and specific device classes, such as Bruno, Spirent, etc.
"""

__author__ = 'Lin Xue (linxue@google.com)'
__author__ = 'Lehan Meng (lmeng@google.com)'


import re

import ip


class Device(object):
  """Base class of all devices.

     information of device class:
     addr: address of device
     user: user name of device
     pwd: password of device
     dev_name: device name
     cmd_prompt: command prompt of device
                (eg. For late iguana of Bruno, it is gfibertv#;
                     before iguana, it is none)
     other: other information of device
  """

  def GetDevInfo(self):
    """This function returns device information."""
    return (self.dev_info['dev_name'], self.dev_info['other'])

  def SetLogging(self, logging):
    """This function set logging for device."""
    self.log = logging
    return
# End of Device class


class Bruno(Device):
  """Bruno device class."""

  def __init__(self, **kwargs):
    """Constructor for Bruno device.

    device name: Bruno, and other device informations
    """
    self.dev_info = {'addr': 'None',
                     'user': 'None',
                     'pwd': 'None',
                     'dev_name': 'None',
                     'cmd_prompt': 'None',
                     'other': 'None'}

    self.dev_info['dev_name'] = 'Bruno'
    for s in kwargs:
      self.dev_info[s] = kwargs[s]
    self.dev_ssh = None

    # Bruno Device attributes
    # serial number
    self.dev_sn = None
    # image version
    self.dev_ver = None
    # ip address
    self.dev_ip = None
    # system time
    self.dev_time = None
    # ACS url
    self.dev_acs = None
    # downloading image
    self.dev_image = None
    # product class
    self.dev_class = None
    # EPG primary
    self.dev_epgpri = None
    # EPG secondary
    self.dev_epgsec = None
    return

  def GetDevCmd(self, cmd='', dev_attr='', dev_log=''):
    """This function sends command to Bruno.

       Then it gets back the results
       If success, save the results and write log
       If fail, show Warning message
    Args:
      cmd:
        the command sent to Bruno system
        to query the device information
      dev_attr:
        the device attribute
        which can be get from this command
      dev_log:
        the logging message to be shown in log
    Returns:
      return the command results
    """
    # Send command to query Bruno device information
    self.dev_ssh.SendCmd(cmd)

    # Get back results
    line = self.dev_ssh.GetCmdOutput(2)[1]

    if line is None:
      info = self.log.CreateErrorInfo('Warning',
                                      'Can not get ' + dev_log)
      self.log.SendLine(None, info)
    else:
      info = self.log.CreateProgressInfo('---',
                                         'Get ' + dev_log + ': ' + line)
      self.log.SendLine(None, info)
      dev_attr = line
    return line.strip()

  def GetSerialNumber(self):
    """This function returns Bruno device serial number."""

    result = self.GetDevCmd(r'hnvram -r 1st_serial_number', self.dev_sn,
                            'serial number')

    return result

  def GetCurrentVersion(self):
    """This function returns Bruno device current image version."""

    result = self.GetDevCmd(r'more /etc/version', self.dev_ver,
                            'current image version')

    return result

  def VerifyCurrentVersion(self, version):
    """Check if the current software version matches the given version.

    Args:
      version: the expected version string to check with device software
    Returns:
      True: if the current version matches the given version
      False: if otherwise
    """
    if version == self.GetCurrentVersion():
      return True
    else:
      return False

  def GetIPaddress(self):
    """This function returns Bruno device IP address."""
    # Obsoleted
    result = self.GetDevCmd(r'ifconfig br0', self.dev_ip,
                            'IP address')

    return result

  def GetDNSServer(self):
    """This function returns device DNS server name."""
    self.dev_ssh.SendCmd('cat /etc/resolv.conf')
    cmd_list = self.dev_ssh.GetCmdOutput()
    dns = None
    for line in cmd_list:
      m = re.search('nameserver (.*)', line)
      if m:
        dns = m.group(1)
        break
    return dns

  def GetTimeServer(self):
    """This function returns device DNS server name."""
    self.dev_ssh.SendCmd('cat /etc/ntpd.conf')
    cmd_list = self.dev_ssh.GetCmdOutput()
    ts = None
    for line in cmd_list:
      m = re.search('server (.*)', line)
      if m:
        ts = m.group(1)
        break
    return ts

  def GetGVSBHost(self):
    """This function returns device GVSB host server name."""
    self.dev_ssh.SendCmd('cat /tmp/gvsbhost')
    cmd_line = self.dev_ssh.GetCmdOutput(2)[0]
    m = re.search('http[s]?://[\w\d\./-]*', cmd_line)
    if m:
      return m.group(0)
    return None

  def GetIPv4Address(self):
    """This function returns Bruno device IPv4 address."""
    self.dev_ssh.SendCmd('ip addr show dev br0')
    cmd_list = self.dev_ssh.GetCmdOutput()
    address = None
    for line in cmd_list:
      if 'inet ' in line and 'scope global' in line:
        address = ip.IPADDR(line).IsLikeIpv4Address()

    if not address:
      info = self.log.CreateErrorInfo('critical',
                                      'Can not detect IPv4 address on device!')
      self.log.SendLine(None, info)
    return address

  def GetIPv6Address(self):
    """This function returns Bruno device IPv6 address.

    This function will return a list of addresses. Sometimes device may
    have multiple IPv6 addresses.

    Returns:
      return the obtained IPv6 address
    """
    self.dev_ssh.SendCmd('ip addr show dev br0')
    cmd_list = self.dev_ssh.GetCmdOutput()
    address = []
    for line in cmd_list:
      if 'inet6 ' in line and 'scope global' in line:
        print line
        m = re.match('inet6 ([\da-f:]+)/\d+ scope global \w*', line.strip())
        if not m:
          info = self.log.CreateErrorInfo(
              'critical', 'Can not detect valid IPv6 address '
              'on device! ' + line)
          self.log.SendLine(None, info)
          return address
        addr = m.group(1)
        address.append(addr)
    return address

  def GetDevTime(self):
    """This function returns Bruno device current date."""

    result = self.GetDevCmd(r'date', self.dev_time,
                            'current date')
    return result

  def GetACSUrl(self):
    """This function returns Bruno device ACS URL."""

    result = self.GetDevCmd(r'cat /tmp/cwmp/acs_url', self.dev_acs,
                            'ACS URL')
    return result

  def VerifyCurrentACSURL(self, url):
    """Check if the current ACS URL matches the given URL.

    Args:
      url: the expected url string to check with device ACS URL
    Returns:
      True: if the current url matches the given url
      False: otherwise
    """
    if url == self.GetACSUrl():
      return True
    else:
      return False

  def GetDnldImage(self):
    """This function returns Bruno device current downloading image."""

    result = self.GetDevCmd(r'ls -l /rw/tr69/dnld', self.dev_image,
                            'current downloading image')

    return result

  def GetProductClass(self):
    """This function returns Bruno device product class."""

    result = self.GetDevCmd(r'cat /etc/platform', self.dev_class,
                            'product class')

    return result

  def GetEpgPrimary(self):
    """This function returns Bruno device primary EPG."""

    result = self.GetDevCmd(r'cat /tmp/epgprimary', self.dev_epgpri,
                            'EPG primary')

    return result

  def GetEpgSecond(self):
    """This function returns Bruno device secondary EPG."""

    result = self.GetDevCmd(r'cat /tmp/epgsecondary', self.dev_epgsec,
                            'EPG secondary')

    return result

  def GetDevInfo(self):
    """This function returns all Bruno device information."""
    # Device name
    info = self.log.CreateProgressInfo('---',
                                       'The device is '
                                       + self.dev_info['dev_name'])
    self.log.SendLine(None, info)

    # Other device informations
    self.GetSerialNumber()
    self.GetCurrentVersion()
    self.GetIPv4Address()
    self.GetDevTime()
    self.GetACSUrl()
    self.GetDnldImage()
    self.GetProductClass()
    self.GetEpgPrimary()
    self.GetEpgSecond()

    return

  def GetTimeStamp(self, line=None):
    """Extract the time information of most current event from Device log.

    i.e., the time that the last event happens since reboot (in seconds)
    Args:
      line: a line of device log which contains event time information.
            If it has value of 'None', then retrieve the last a few lines from
            device log to extract time information.
    Returns:
      return the time stamp string if succeed, return -1 otherwise.
    """
    if not line:
      # get time stamp from Device log file
      self.dev_ssh.SendCmd('dmesg | grep cwmpd:')
      log_list = self.dev_ssh.GetCmdOutput()

      for line in log_list:
        m = re.match('\\[[\s]*(\d*\\.\d{3})\\]', line)
        if m:
          # Match, return the time stamp
          return m.group(1)
    else:
      # get time stamp from a Device log line
      m = re.match('\\[[\s]*(\d*\\.\d{3})\\]', line)
      if m:
      # Match, return the time stamp
        return m.group(1)
    # No time stamp found
    return -1

  def FindLineInLog(self, log_list, time_stamp, pattern_line):
    """Match a particular string from device logs.

    Find a particular string or line from device log
    Args:
      log_list: the device log to search from
      time_stamp: to search events that are after this time
      pattern_line: the string or line that need to be matched in device log
    Returns:
      True: if 'line' matched
      False: 'line' not found in device log
    """
    m = re.compile(pattern_line)
    for line in log_list:
      if float(self.GetTimeStamp(line)) > float(time_stamp):
        #Debug
        if 'detected' in line:
          print 'here'

        matching = m.search(line)
        if matching:
          return True
    return False
# End of Bruno device class


class Spirent(Device):
  """Spirent device class."""

  def __init__(self, **kwargs):
    """Constructor for Spirent device.

        device name: Spirent, and other device informations
    """

    self.dev_info['dev_name'] = 'Spirent'
    for s in ('addr', 'user', 'pwd', 'cmd_prompt', 'other'):
      if s in kwargs:
        self.dev_info[s] = kwargs[s]

# End of Spirent device class
