# Coded by Dream Elite Team

from Components.Converter.Converter import Converter
from Components.Element import cached
from enigma import eTimer
from enigma import iServiceInformation, iPlayableService
from DE.DELibrary import Tool
t = Tool()

from Components.DEEcmDict import setEcmDict, getEcmDict

class DEEcmInfo(Converter, object):

	ECM_TIME = 0
	CA_ID = 1
	PID = 2
	HOPS = 3
	CRYPT = 4
	READER_ADDRESS = 5
	EMU_NAME = 6

	def __init__(self, type):
		Converter.__init__(self, type)

		converter_types = {	"EcmTime":			(self.ECM_TIME, True, 5000, self.getEcmTimeText),
							"CaID":				(self.CA_ID, True, 5000, self.getCaidText),
							"Pid":				(self.PID, True, 5000, self.getPidText),
							"Hops":				(self.HOPS, True, 5000, self.getHopsText),
							"Crypt":			(self.CRYPT, True, 5000, self.getCryptText),
							"ReaderAddress":	(self.READER_ADDRESS, True, 5000, self.getReaderAddressText),
							"EmuActive":		(self.EMU_NAME, False, 60000, self.getEmuActiveText)}
		self.systemCaids = {"01" : "Seca",
							"05" : "Viaccess",
							"06" : "Irdeto",
							"09" : "NDS",
							"0B" : "Conax",
							"0D" : "CryptoWorks",
							"17" : "BetaCrypt",
							"18" : "Nagravision",
							"26" : "BiSS"}

		args = type.split(",")
		converter_type = (args[0] in converter_types and args.pop(0)) or (args.pop(0) in converter_types or "Crypt")

		self.type, self.poll_enabled, self.poll_interval, self.funcText = converter_types[converter_type]

		if args:
			self.poll_enabled = (args[0] == "Poll" and args.pop(0) == "Poll") or (not (args[0] == "NoPoll" and args.pop(0) == "NoPoll") and (args.pop(0) in ["Poll","NoPoll"] or self.poll_enabled))
		if self.poll_enabled:
			if args and args[0].isdigit:
				self.poll_interval = max(1, int(args[0])) * 1000
		del args
		if self.type == self.EMU_NAME:
			self.poll_enabled = False

		self.poll_timer = eTimer()
		try:
			self.poll_timer_conn = self.poll_timer.timeout.connect(self.poll)
		except:
			self.poll_timer.callback.append(self.poll)

	@cached
	def getText(self):
		text = self.funcText()
		return text

	text = property(getText)

	def getServiceInfoObject(self):
		service = self.source.service
		if service:
			return service and service.info()

	def getEcmTimeText(self):
		ecm_info = getEcmDict()
		ecm_time = ecm_info.get("ecm time", "")
		if ecm_time:
			if "msec" in ecm_time:
				return "%s" % ecm_time
			elif ecm_time != "nan":
				return "%ss" % ecm_time
			else:
				return "0.000s"
		else:
			return "0.000s"

	def getCaidText(self):
		info = self.getServiceInfoObject()
		if info:
			if info.getInfo(iServiceInformation.sIsCrypted):
				ecm_info = getEcmDict()
				caid = ecm_info.get("caid", "")
				if caid:
					caid = caid.lstrip("0x").upper().zfill(4)
					return "CaID: %s" % caid
				else:
					return "Crypted"
			else:
				return "FTA"
		else:
			return "????"

	def getPidText(self):
		ecm_info = getEcmDict()
		pid = ecm_info.get("pid", "")
		if pid:
			pid = pid.lstrip("0x").upper().zfill(4)
			return "ECMPid: %s" % pid
		else:
			return "ECMPid: N/A"

	def getHopsText(self):
		ecm_info = getEcmDict()
		hops = ecm_info.get("hops", "")
		return hops or "#"

	def getCryptText(self):
		info = self.getServiceInfoObject()
		if info:
			if info.getInfo(iServiceInformation.sIsCrypted):
				ecm_info = getEcmDict()
				emu_caid = ecm_info.get("caid", "")
				if emu_caid:
					emu_caid = emu_caid.lstrip("0x")
					if len(emu_caid) == 3:
						emu_caid = "0%s" % emu_caid
					emu_caid = emu_caid[:2].upper()
					return self.systemCaids.get(emu_caid, "Unknown")
				else:
					return "Crypted"
			else:
				return "FTA"
		else:
			return "????"

	def getReaderAddressText(self):
		readeraddresstext = "????"
		info = self.getServiceInfoObject()
		if info:
			readeraddresstext = "FTA"
			if info.getInfo(iServiceInformation.sIsCrypted):
				readeraddresstext = "Crypted"
				ecm_info = getEcmDict()
				if ecm_info:
					protocol = ecm_info.get("protocol", "")	# emu oscam
					using = ecm_info.get("using", "")		# emu cccam
					if protocol:	# emu oscam
						if protocol == "internal":
							readeraddresstext = "Internal Slot"
						elif protocol in ("smartreader","mouse","serial","pcsc","sc8in1","smargo",):
							readeraddresstext = "USB Reader"
						else:
							readeraddresstext = ecm_info.get("from", "")
					elif using:		# emu cccam
						if using == "emu":
							readeraddresstext = "EMU"
						else:
							address = ecm_info.get("address", "")
							if address:
								if address == "/dev/sci0":
									readeraddresstext = "Slot #1"
								elif address == "/dev/sci1":
									readeraddresstext = "Slot #2"
								elif address.find("/dev/ttyUSB") >= 0:
									readeraddresstext = "USB Reader"
								else:
									readeraddresstext = address
		return readeraddresstext

	def getEmuActiveText(self):
		emuname = t.readEmuName(t.readEmuActive()).strip()
		emuactive = emuname != "None" and emuname or t.readEmuName(t.readCrdsrvActive()).strip()
		return emuactive

	def ecmfile(self):
		ecm = None
		ecmdict = {}
		service = self.source.service
		if service:
			frontendInfo = service.frontendInfo()
			if frontendInfo:
				try:
					ecm = open("/tmp/ecm.info", "rb").readlines()
				except:
					pass
			if ecm:
				for line in ecm:
					x = line.lower().find("msec")
					if x != -1:
						ecmdict["ecm time"] = line[0:x+4]
					elif line.lower().find("response:") != -1:
						y = line.lower().find("response:")
						if y != -1:
							ecmdict["ecm time"] = line[y+9:].strip("\n\r")
					else:
						item = line.split(":", 1)
						if len(item) > 1:
							ecmdict[item[0].strip().lower()] = item[1].strip()
						else:
							if not ecmdict.has_key("caid"):
								x = line.lower().find("caid")
								if x != -1:
									y = line.find(",")
									if y != -1:
										ecmdict["caid"] = line[x+5:y]
		setEcmDict(ecmdict)

	def poll(self, poll_enabled = True, return_to_suspend = False):
		if poll_enabled:
			self.poll_timer.start(self.poll_interval)
			self.changed((self.CHANGED_POLL,), return_to_suspend = return_to_suspend)
		else:
			self.poll_timer.stop()

	def doSuspend(self, suspended):
		if not suspended and self.type == self.EMU_NAME:
			Converter.changed(self, (self.CHANGED_ALL,))
			return
		if self.poll_enabled:
			if not suspended:
				self.poll(return_to_suspend = True)
			else:
				self.poll(poll_enabled = False)
		else:
			if not suspended:
				self.changed((self.CHANGED_ALL,), return_to_suspend = True)

	def destroy(self):
		self.poll_timer.stop()
		try:
			del self.poll_timer_conn
		except:
			self.poll_timer.callback.remove(self.poll)
		del self.poll_timer

	def changed(self, what, return_to_suspend = False):
		if self.type == self.EMU_NAME:
			return
		if not self.suspended or return_to_suspend:
			if not self.type:
				self.ecmfile()
			Converter.changed(self, what)
