#!/usr/bin/env python

# This file is part of Window-Switch.
# Copyright (c) 2009-2013 Antoine Martin <antoine@nagafix.co.uk>
# Window-Switch is released under the terms of the GNU GPL v3


import sys
SYS_WTMP_FILE = "/var/log/wtmp"

DEBUG="--debug-utmp" in sys.argv

from winswitch.util.simple_logger import Logger
logger=Logger("utmp_wrapper", log_colour=Logger.CRIMSON)


class utmp_rec:
	"""
	The utmp record we expose.
	Independant of whether we retrieve it from python-utmp or pyutmp.
	"""

	def	__init__(self):
		self.ut_type = None
		self.ut_pid = None
		self.ut_line = None
		self.ut_id = None
		self.ut_user = None
		self.ut_host = None
		self.ut_exit = None
		self.ut_session = None
		self.ut_time = None
		self.ut_addr = None

	def __str__(self):
		values = [self.ut_type, self.ut_pid, self.ut_line, self.ut_id, self.ut_user, self.ut_host, self.ut_exit, self.ut_session, self.ut_time, self.ut_addr]
		return	" ".join([str(t) for t in values])


def python_utmp_getutents(user_only=True):
	"""
	Extract utmp data using python-utmp
	"""
	from UTMPCONST import UTMP_FILE, USER_PROCESS		#@UnresolvedImport
	import utmp											#@UnresolvedImport
	urecs = utmp.UtmpRecord(UTMP_FILE)
	latest = {}
	while (1):
		ute = urecs.getutent()
		if not ute:
			break
		if user_only and ute[0]!=USER_PROCESS:
			continue
		rec = utmp_rec()
		#Fields: 'ut_addr_v6', 'ut_exit', 'ut_host', 'ut_id', 'ut_line', 'ut_pid', 'ut_session', 'ut_tv', 'ut_type', 'ut_user'
		for f in ['ut_exit', 'ut_host', 'ut_id', 'ut_line', 'ut_pid', 'ut_session', 'ut_type', 'ut_user']:
			setattr(rec, f, getattr(ute, f))
		if rec.ut_line.endswith(rec.ut_line):
			rec.ut_id = rec.ut_line
		if rec.ut_exit==(0,0):
			rec.ut_exit = 0
		if rec.ut_session==0:
			rec.ut_session = None
		rec.ut_addr = ute.ut_addr_v6
		try:
			rec.ut_time = long(ute.ut_tv[0])
		except:
			rec.ut_time = 0
		current = latest.get(rec.ut_id)
		if current is None or current.ut_time<rec.ut_time:
			latest[rec.ut_id] = rec
	recs = latest.values()
	return recs

def pyutmp_getutents(user_only=True):
	"""
	Extract utmp data using pyutmp
	"""
	from pyutmp import UtmpFile		#@UnresolvedImport
	recs = []
	for ute in UtmpFile():
		if user_only:
			""" skip non-user events like reboots """
			if not ute.ut_user_process:
				continue
			if hasattr(ute, "ut_type") and ute.ut_type!='USER_PROCESS':
				continue
		rec = utmp_rec()
		for f in ['ut_addr', 'ut_host', 'ut_id', 'ut_pid', 'ut_session', 'ut_type', 'ut_user']:
			if hasattr(ute, f):
				setattr(rec, f, getattr(ute, f))
		rec.ut_line = ute.ut_line.replace("/dev/", "")
		if hasattr(ute, "ut_exit_code"):
			rec.ut_exit = ute.ut_exit_code
		rec.ut_time = ute.ut_time
		recs.append(rec)
	return recs

getutents = None

ARGV_PARAM = "--getutents="
for x in sys.argv:
	if x.startswith(ARGV_PARAM):
		method=x[len(ARGV_PARAM):]
		if globals()[method]:
			getutents = globals()[method]

def find_best_utmp_impl():
	from winswitch.globals import WIN32
	if WIN32:
		return	None
	try:
		import utmp				#@UnresolvedImport
		assert utmp
		from UTMPCONST import WTMP_FILE		#@UnresolvedImport
		SYS_WTMP_FILE = WTMP_FILE
		return	python_utmp_getutents
	except Exception, e:
		logger.slog("cannot load utmp: %s" % e)
	try:
		import pyutmp					#@UnresolvedImport
		assert pyutmp
		return	pyutmp_getutents
	except Exception, e:
		logger.slog("cannot load pyutmp: %s" % e)
	logger.serror("no utmp module available!")
	return	None

if getutents==None:
	getutents = find_best_utmp_impl()
	logger.slog("getutents=%s" % getutents)

def main():
	from winswitch.util.common import csv_list
	ut = getutents()
	logger.slog("getutents()=%s" % csv_list(ut))
	i = 0
	for x in ut:
		logger.slog("getutents() [%s]=%s" % (i, x))
		i += 1

if __name__ == "__main__":
	main()
