import re
from SCons.Script import *  # the usual scons stuff you get in a SConscript
import collections

def generate(env):
    """
    Add builders and construction variables for the
    SubstInFile tool.

    Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
    from the source to the target.
    The values of SUBST_DICT first have any construction variables expanded
    (its keys are not expanded).
    If a value of SUBST_DICT is a python callable function, it is called and
    the result is expanded as the value.
    If there's more than one source and more than one target, each target gets
    substituted from the corresponding source.
    """
    def do_subst_in_file(targetfile, sourcefile, dict):
        """Replace all instances of the keys of dict with their values.
        For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
        then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
        """
        try:
            f = open(sourcefile, 'rb')
            contents = f.read()
            f.close()
        except:
            raise SCons.Errors.UserError("Can't read source file %s"%sourcefile)
        for (k,v) in list(dict.items()):
            contents = re.sub(k, v, contents)
        try:
            f = open(targetfile, 'wb')
            f.write(contents)
            f.close()
        except:
            raise SCons.Errors.UserError("Can't write target file %s"%targetfile)
        return 0 # success

    def subst_in_file(target, source, env):
        if 'SUBST_DICT' not in env:
            raise SCons.Errors.UserError("SubstInFile requires SUBST_DICT to be set.")
        d = dict(env['SUBST_DICT']) # copy it
        for (k,v) in list(d.items()):
            if isinstance(v, collections.Callable):
                d[k] = env.subst(v()).replace('\\','\\\\')
            elif SCons.Util.is_String(v):
                d[k] = env.subst(v).replace('\\','\\\\')
            else:
                raise SCons.Errors.UserError("SubstInFile: key %s: %s must be a string or callable"%(k, repr(v)))
        for (t,s) in zip(target, source):
            return do_subst_in_file(str(t), str(s), d)

    def subst_in_file_string(target, source, env):
        """This is what gets printed on the console."""
        return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
                          for (t,s) in zip(target, source)])

    def subst_emitter(target, source, env):
        """Add dependency from substituted SUBST_DICT to target.
        Returns original target, source tuple unchanged.
        """
        d = env['SUBST_DICT'].copy() # copy it
        for (k,v) in list(d.items()):
            if isinstance(v, collections.Callable):
                d[k] = env.subst(v())
            elif SCons.Util.is_String(v):
                d[k]=env.subst(v)
        Depends(target, SCons.Node.Python.Value(d))
        return target, source

##    env.Append(TOOLS = 'substinfile')       # this should be automaticaly done by Scons ?!?
    subst_action = SCons.Action.Action( subst_in_file, subst_in_file_string )
    env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)

def exists(env):
    """
    Make sure tool exists.
    """
    return True
