#!/usr/bin/python
###############################################################################
#                                                                             #
# Fireinfo                                                                    #
# Copyright (C) 2010, 2011 IPFire Team (www.ipfire.org)                       #
#                                                                             #
# This program is free software: you can redistribute it and/or modify        #
# it under the terms of the GNU General Public License as published by        #
# the Free Software Foundation, either version 3 of the License, or           #
# (at your option) any later version.                                         #
#                                                                             #
# This program is distributed in the hope that it will be useful,             #
# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
# GNU General Public License for more details.                                #
#                                                                             #
# You should have received a copy of the GNU General Public License           #
# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
#                                                                             #
###############################################################################

import os.path

class Device(object):
	"""
		This is an abstract class that represents all devices in the system.
		Every single device has its own instance of this class.
	"""

	def __init__(self, path):
		"""
			Collect all information about the device by reading the
			"uevent" file and parsing it.
		"""

		# Save the path in /sys to the device.
		self.path = path

		# Datastructure to store information we read.
		self._uevent = {}

		# Open the uevent file and parse all lines.
		with open(os.path.join(path, "uevent")) as f:
			for line in f.readlines():
				key, val = line.split("=")
				self._uevent[key] = val.rstrip().lower()

	@property
	def driver(self):
		"""
			Get the driver/kernel module that device is driven by or return None.
		"""
		return self._uevent.get("DRIVER", None)

			
class PCIDevice(Device):
	"""
		A class that represents all PCI (and PCIe) devices in a system.
	"""

	subsystem = "pci"

	@property
	def model(self):
		"""
			Return the PCI model id of this device.
		"""
		return self._uevent['PCI_ID'].split(":")[1]
		
	@property
	def vendor(self):
		"""
			Return the PCI vendor id of this device.
		"""
		return self._uevent['PCI_ID'].split(":")[0]

	@property
	def deviceclass(self):
		"""
			Return the PCI device class of this device.
		"""
		return self._uevent['PCI_CLASS']

	@property
	def sub_vendor(self):
		"""
			Return the PCI vendor sub id of this device.
		"""
		return self._uevent["PCI_SUBSYS_ID"].split(":")[0]

	@property
	def sub_model(self):
		"""
			Return the PCI model sub id of this device.
		"""
		return self._uevent["PCI_SUBSYS_ID"].split(":")[1]


class USBDevice(Device):
	"""
		A class that represents all USB devices in a system.
	"""

	subsystem = "usb"
	
	def pad(self, s):
		"""
			A function to pad ids that have no leading zeroes.
		"""
		while len(s) < 4:
			s = "0"+s
		return s

	@property
	def vendor(self):
		"""
			Return the USB vendor id of this device.
		"""
		return self.pad(self._uevent['PRODUCT'].split("/")[0])

	@property
	def model(self):
		"""
			Return the USB model id of this device.
		"""
		return self.pad(self._uevent['PRODUCT'].split("/")[1])

	@property
	def deviceclass(self):
		"""
			Return the USB device class of this device.
		"""
		return self._uevent.get("INTERFACE", None)
