# This file contains waf optimisations for Samba

# most of these optimisations are possible because of the restricted build environment
# that Samba has. For example, Samba doesn't attempt to cope with Win32 paths during the
# build, and Samba doesn't need build varients

# overall this makes some build tasks quite a bit faster

from TaskGen import feature, after
import preproc, Task

@feature('cc', 'cxx')
@after('apply_type_vars', 'apply_lib_vars', 'apply_core')
def apply_incpaths(self):
	lst = []

	try:
		kak = self.bld.kak
	except AttributeError:
		kak = self.bld.kak = {}

	# TODO move the uselib processing out of here
	for lib in self.to_list(self.uselib):
		for path in self.env['CPPPATH_' + lib]:
			if not path in lst:
				lst.append(path)
	if preproc.go_absolute:
		for path in preproc.standard_includes:
			if not path in lst:
				lst.append(path)

	for path in self.to_list(self.includes):
		if not path in lst:
			if preproc.go_absolute or path[0] != '/': #os.path.isabs(path):
				lst.append(path)
			else:
				self.env.prepend_value('CPPPATH', path)

	for path in lst:
		node = None
		if path[0] == '/': # os.path.isabs(path):
			if preproc.go_absolute:
				node = self.bld.root.find_dir(path)
		elif path[0] == '#':
			node = self.bld.srcnode
			if len(path) > 1:
				try:
					node = kak[path]
				except KeyError:
					kak[path] = node = node.find_dir(path[1:])
		else:
			try:
				node = kak[(self.path.id, path)]
			except KeyError:
				kak[(self.path.id, path)] = node = self.path.find_dir(path)

		if node:
			self.env.append_value('INC_PATHS', node)

@feature('cc')
@after('apply_incpaths')
def apply_obj_vars_cc(self):
    """after apply_incpaths for INC_PATHS"""
    env = self.env
    app = env.append_unique
    cpppath_st = env['CPPPATH_ST']

    lss = env['_CCINCFLAGS']

    try:
         cac = self.bld.cac
    except AttributeError:
         cac = self.bld.cac = {}

    # local flags come first
    # set the user-defined includes paths
    for i in env['INC_PATHS']:

        try:
            lss.extend(cac[i.id])
        except KeyError:

            cac[i.id] = [cpppath_st % i.bldpath(env), cpppath_st % i.srcpath(env)]
            lss.extend(cac[i.id])

    env['_CCINCFLAGS'] = lss
    # set the library include paths
    for i in env['CPPPATH']:
        app('_CCINCFLAGS', cpppath_st % i)

import Node, Environment

def vari(self):
	return "default"
Environment.Environment.variant = vari

def variant(self, env):
	if not env: return 0
	elif self.id & 3 == Node.FILE: return 0
	else: return "default"
Node.Node.variant = variant


import TaskGen, Task

def create_task(self, name, src=None, tgt=None):
    task = Task.TaskBase.classes[name](self.env, generator=self)
    if src:
        task.set_inputs(src)
    if tgt:
        task.set_outputs(tgt)
    return task
TaskGen.task_gen.create_task = create_task

def hash_constraints(self):
	a = self.attr
	sum = hash((str(a('before', '')),
            str(a('after', '')),
            str(a('ext_in', '')),
            str(a('ext_out', '')),
            self.__class__.maxjobs))
	return sum
Task.TaskBase.hash_constraints = hash_constraints


# import cc
# from TaskGen import extension
# import Utils

# @extension(cc.EXT_CC)
# def c_hook(self, node):
# 	task = self.create_task('cc', node, node.change_ext('.o'))
# 	try:
# 		self.compiled_tasks.append(task)
# 	except AttributeError:
# 		raise Utils.WafError('Have you forgotten to set the feature "cc" on %s?' % str(self))

# 	bld = self.bld
# 	try:
# 		dc = bld.dc
# 	except AttributeError:
# 		dc = bld.dc = {}

# 	if task.outputs[0].id in dc:
# 		raise Utils.WafError('Samba, you are doing it wrong %r %s %s' % (task.outputs, task.generator, dc[task.outputs[0].id].generator))
# 	else:
# 		dc[task.outputs[0].id] = task

# 	return task


def suncc_wrap(cls):
	'''work around a problem with cc on solaris not handling module aliases
	which have empty libs'''
	if getattr(cls, 'solaris_wrap', False):
		return
	cls.solaris_wrap = True
	oldrun = cls.run
	def run(self):
		if self.env.CC_NAME == "sun" and not self.inputs:
			self.env = self.env.copy()
			self.env.append_value('LINKFLAGS', '-')
		return oldrun(self)
	cls.run = run
suncc_wrap(Task.TaskBase.classes['cc_link'])