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

"""This class defines devices."""

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

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

"""
import logging
import os

import ssh


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
  """
  devInfo = {'addr': 'None',
             'user': 'None',
             'pwd': 'None',
             'dev_name': 'None',
             'cmd_prompt': 'None',
             'other': 'None'}

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

# End of Device class


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

  dev_ssh = None

  def __init__(self, **kwargs):
    """ Constructor for Bruno device
        device name: Bruno, and other device informations
    """
    self.devInfo['dev_name'] = 'Bruno'
    for s in ('addr', 'user', 'pwd', 'cmd_prompt', 'other'):
      if s in kwargs:
        self.devInfo[s] = kwargs[s]

    self.log = logging.Logging()

  def createSSH(self):
    """This function creates SSH tunnel to Bruno device."""
    self.bruno = Bruno(usr=self.devInfo['user'],
                       addr=self.devInfo['addr'],
                       pwd=self.devInfo['pwd'],
                       cmd_prompt=self.devInfo['cmd_prompt'])

    self.dev_ssh = ssh.SSH(self.bruno)

    if self.dev_ssh.ssh() < 0:
      info = self.log.createErrorInfo('critical',
                                      'Cannot establish ssh tunnel to Device! '
                                      'Exit!')
      self.log.sendLine(None, info)
      os.sys.exit(-1)
    else:
      info = self.log.createProgressInfo('---',
                                         'ssh session to Device '
                                         'successfully established!')
      self.log.sendLine(None, info)
    return self.dev_ssh

  def closeSSH(self):
    """This function closes SSH tunnel to Bruno device."""
    self.dev_ssh.close()

  def getSerialNumber(self):
    """This function returns Bruno device serial number."""
    self.dev_ssh.sendCmd(r'hnvram -r 1st_serial_number')
    line = self.dev_ssh.getCmdOutput(2)[1]
    if line is None:
      info = self.log.createErrorInfo('Warning',
                                      'Can not get serial number')
      self.log.sendLine(None, info)
    else:
      info = self.log.createProgressInfo('---',
                                         'Get serial number: ' + line)
      self.log.sendLine(None, info)

  def getCurrentVersion(self):
    """This function returns Bruno device current software image version."""
    self.dev_ssh.sendCmd(r'more /etc/version')
    line = self.dev_ssh.getCmdOutput(2)[1]
    if line is None:
      info = self.log.createErrorInfo('Warning',
                                      'Can not get current image version')
      self.log.sendLine(None, info)
    else:
      info = self.log.createProgressInfo('---',
                                         'Get current image version: ' + line)
      self.log.sendLine(None, info)

  def getIPAddress(self):
    """This function returns Bruno device IP address."""
    self.dev_ssh.sendCmd(r'ifconfig br0')
    line = self.dev_ssh.getCmdOutput(2)[1]
    if line is None:
      info = self.log.createErrorInfo('Warning',
                                      'Can not get ip address')
      self.log.sendLine(None, info)
    else:
      info = self.log.createProgressInfo('---',
                                         'Get IP address: ' + line)
      self.log.sendLine(None, info)

  def getDevTime(self):
    """This function returns Bruno device current date."""
    self.dev_ssh.sendCmd(r'date')
    line = self.dev_ssh.getCmdOutput(2)[1]
    if line is None:
      info = self.log.createErrorInfo('Warning',
                                      'Can not get current date')
      self.log.sendLine(None, info)
    else:
      info = self.log.createProgressInfo('---',
                                         'Get current date: ' + line)
      self.log.sendLine(None, info)

  def getACSUrl(self):
    """This function returns Bruno device ACS URL."""
    self.dev_ssh.sendCmd(r'cat /tmp/cwmp/acs_url')
    line = self.dev_ssh.getCmdOutput(2)[1]
    if line is None:
      info = self.log.createErrorInfo('Warning',
                                      'Can not get ACS url')
      self.log.sendLine(None, info)
    else:
      info = self.log.createProgressInfo('---',
                                         'Get ACS URL: ' + line)
      self.log.sendLine(None, info)

  def getDnldImage(self):
    """This function returns Bruno device current downloading image."""
    self.dev_ssh.sendCmd(r'ls -l /rw/tr69/dnld')
    line = self.dev_ssh.getCmdOutput(2)[1]
    if line is None:
      info = self.log.createErrorInfo('Warning',
                                      'Can not get current downloading image')
      self.log.sendLine(None, info)
    else:
      info = self.log.createProgressInfo('---',
                                         'Get current downloading image: '
                                         + line)
      self.log.sendLine(None, info)

  def getDevInfo(self):
    """This function returns all Bruno device information."""
    print "This device is: " + self.devInfo['dev_name']
    self.getSerialNumber()
    self.getCurrentVersion()
    self.getIPAddress()
    self.getDevTime()
    self.getACSUrl()
    self.getDnldImage()

# 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.devInfo['dev_name'] = 'Spirent'
    for s in ('addr', 'user', 'pwd', 'cmd_prompt', 'other'):
      if s in kwargs:
        self.devInfo[s] = kwargs[s]

# End of Spirent device class
