#! /usr/bin/env python

from waflib import Task, Errors
from waflib.Tools import c

def options(opt):
	opt.load('compiler_c')


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


def build(bld):
	bld(features = 'c cprogram',
		target   = 'test',
		source   = 'src/main.c src/test.c',
		includes = 'src')

class mock(Task.Task):
	run_str = 'cp ${SRC} ${TGT}'
	color   = 'BLUE'


# it would be better to replace the scan() method, but this is doable too

def runnable_status(self):

	ret = self.runnable_status_dynamic_headers2()

	if ret != Task.ASK_LATER and not getattr(self, 'all_mock_done', False):
		self.all_mock_done = True # run once


		bld = self.generator.bld
		add = False

		try:
			mock_tasks = bld.mock_tasks
		except AttributeError:
			mock_tasks = bld.mock_tasks = {}

		for x in bld.raw_deps[self.uid()]:
			if x.startswith('mock_'):
				h_file = x[5:]
				for k in [self.inputs[0].parent] + self.generator.includes_nodes:
					h_node = k.find_node(h_file)
					if h_node:
						break

				if not h_node:
					raise Errors.WafError('no header for %s' % x)

				m_node = h_node.parent.find_or_declare(x)
				try:
					tsk = mock_tasks[m_node]
				except KeyError:
					tsk = mock_tasks[m_node] = self.generator.create_task('mock', [h_node], [m_node])
					bld.producer.outstanding.append(tsk)
					bld.producer.total += 1

					# preprocessor cache :-/
					try:
						for key in list(bld.cache_nd.keys()):
							if key[1] == x:
								del bld.cache_nd[key]
					except (KeyError, AttributeError):
						pass

				add = True
				self.set_run_after(tsk)

		if add:
			# recompute the task signature
			delattr(self, 'cache_sig')
			del bld.imp_sigs[self.uid()]
			return self.runnable_status()

		for x in bld.node_deps[self.uid()]:
			if x.name.startswith('mock_'):
				h_node = x.parent.get_src().find_node(x.name[5:])
				if not h_node:
					raise Errors.WafError('no header for %s' % x.name)

				try:
					tsk = mock_tasks[x]
				except KeyError:
					tsk = mock_tasks[x] = self.generator.create_task('mock', [h_node], [x])
					bld.producer.outstanding.append(tsk)
					bld.producer.total += 1

				add = True
				self.set_run_after(tsk)

				# node get_bld_sig cache :-/
				try:
					delattr(x, 'cache_sig')
				except AttributeError:
					pass
		if add:
			# recompute the task signature
			delattr(self, 'cache_sig')
			return self.runnable_status()

	return ret

c.c.runnable_status_dynamic_headers2 = c.c.runnable_status
c.c.runnable_status = runnable_status

