#! /usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2010 (ita)

"""
This tool modifies the task signature scheme to store and obtain
information about the task execution (why it must run, etc)::

	def configure(conf):
		conf.load('why')

After adding the tool, a full rebuild is necessary:
waf clean build --zones=task
"""

from waflib import Task, Utils, Logs, Errors

def signature(self):
	# compute the result one time, and suppose the scan_signature will give the good result
	try:
		return self.cache_sig
	except AttributeError:
		pass

	self.m = Utils.md5(usedforsecurity=False)
	self.m.update(self.hcode)
	id_sig = self.m.digest()

	# explicit deps
	self.m = Utils.md5(usedforsecurity=False)
	self.sig_explicit_deps()
	exp_sig = self.m.digest()

	# env vars
	self.m = Utils.md5(usedforsecurity=False)
	self.sig_vars()
	var_sig = self.m.digest()

	# implicit deps / scanner results
	self.m = Utils.md5(usedforsecurity=False)
	if self.scan:
		try:
			self.sig_implicit_deps()
		except Errors.TaskRescan:
			return self.signature()
	impl_sig = self.m.digest()

	ret = self.cache_sig = impl_sig + id_sig + exp_sig + var_sig
	return ret


Task.Task.signature = signature

old = Task.Task.runnable_status
def runnable_status(self):
	ret = old(self)
	if ret == Task.RUN_ME:
		try:
			old_sigs = self.generator.bld.task_sigs[self.uid()]
		except (KeyError, AttributeError):
			Logs.debug("task: task must run as no previous signature exists")
		else:
			new_sigs = self.cache_sig
			def v(x):
				return Utils.to_hex(x)

			Logs.debug('Task %r', self)
			msgs = ['* Implicit or scanner dependency', '* Task code', '* Source file, explicit or manual dependency', '* Configuration data variable']
			tmp = 'task: -> %s: %s %s'
			for x in range(len(msgs)):
				l = len(Utils.SIG_NIL)
				a = new_sigs[x*l : (x+1)*l]
				b = old_sigs[x*l : (x+1)*l]
				if (a != b):
					Logs.debug(tmp, msgs[x].ljust(35), v(a), v(b))
	return ret
Task.Task.runnable_status = runnable_status

