# Copyright (c) 2004-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert

import imp
import py_compile
import sys
import zipfile

from os.path import basename
from os.path import exists

class DictImporter(object):
    '''This importer takes a dictionary of arbitrary module names that
    map to arbitrary filenames.'''
    def __init__(self, modules, build_env):
        self.modules = modules
        self.installed = set()
        self.build_env = build_env

    def __del__(self):
        self.unload()

    def unload(self):
        import sys
        for module in self.installed:
            del sys.modules[module]
        self.installed = set()

    def find_module(self, fullname, path):
        if fullname == '__scons':
            return self

        if fullname == 'm5.objects':
            return self

        if fullname.startswith('m5.internal'):
            return None

        if fullname in self.modules and exists(self.modules[fullname]):
            return self

        return None

    def load_module(self, fullname):
        mod = imp.new_module(fullname)
        sys.modules[fullname] = mod
        self.installed.add(fullname)

        mod.__loader__ = self
        if fullname == 'm5.objects':
            mod.__path__ = fullname.split('.')
            return mod

        if fullname == '__scons':
            mod.__dict__['m5_build_env'] = self.build_env
            return mod

        srcfile = self.modules[fullname]
        if basename(srcfile) == '__init__.py':
            mod.__path__ = fullname.split('.')
        mod.__file__ = srcfile

        exec file(srcfile, 'r') in mod.__dict__

        return mod

class ordered_dict(dict):
    def keys(self):
        keys = super(ordered_dict, self).keys()
        keys.sort()
        return keys

    def values(self):
        return [ self[key] for key in self.keys() ]

    def items(self):
        return [ (key,self[key]) for key in self.keys() ]

    def iterkeys(self):
        for key in self.keys():
            yield key

    def itervalues(self):
        for value in self.values():
            yield value

    def iteritems(self):
        for key,value in self.items():
            yield key, value

class Generate(object):
    def __init__(self, py_sources, sim_objects, build_env):
        self.py_sources = py_sources
        self.py_modules = {}
        for source in py_sources:
            self.py_modules[source.modpath]  = source.srcpath

        importer = DictImporter(self.py_modules, build_env)

        # install the python importer so we can grab stuff from the source
        # tree itself.
        sys.meta_path[0:0] = [ importer ]

        import m5
        self.m5 = m5

        # import all sim objects so we can populate the all_objects list
        # make sure that we're working with a list, then let's sort it
        sim_objects = list(sim_objects)
        sim_objects.sort()
        for simobj in sim_objects:
            exec('from m5.objects import %s' % simobj)

        # we need to unload all of the currently imported modules so that they
        # will be re-imported the next time the sconscript is run
        importer.unload()
        sys.meta_path.remove(importer)

        self.sim_objects = m5.SimObject.allClasses
        self.enums = m5.params.allEnums

        self.params = {}
        for name,obj in self.sim_objects.iteritems():
            for param in obj._params.local.values():
                if not hasattr(param, 'swig_decl'):
                    continue
                pname = param.ptype_str
                if pname not in self.params:
                    self.params[pname] = param

    def createSimObjectParam(self, target, source, env):
        assert len(target) == 1 and len(source) == 1

        hh_file = file(target[0].abspath, 'w')
        name = str(source[0].get_contents())
        obj = self.sim_objects[name]

        print >>hh_file, obj.cxx_decl()

    # Generate Python file containing a dict specifying the current
    # build_env flags.
    def makeDefinesPyFile(self, target, source, env):
        f = file(str(target[0]), 'w')
        print >>f, "m5_build_env = ", source[0]
        f.close()

    # Generate python file containing info about the M5 source code
    def makeInfoPyFile(self, target, source, env):
        f = file(str(target[0]), 'w')
        for src in source:
            data = ''.join(file(src.srcnode().abspath, 'r').xreadlines())
            print >>f, "%s = %s" % (src, repr(data))
        f.close()

    # Generate the __init__.py file for m5.objects
    def makeObjectsInitFile(self, target, source, env):
        f = file(str(target[0]), 'w')
        print >>f, 'from params import *'
        print >>f, 'from m5.SimObject import *'
        for module in source:
            print >>f, 'from %s import *' % module.get_contents()
        f.close()

    def createSwigParam(self, target, source, env):
        assert len(target) == 1 and len(source) == 1

        i_file = file(target[0].abspath, 'w')
        name = str(source[0].get_contents())
        param = self.params[name]

        for line in param.swig_decl():
            print >>i_file, line

    def createEnumStrings(self, target, source, env):
        assert len(target) == 1 and len(source) == 1

        cc_file = file(target[0].abspath, 'w')
        name = str(source[0].get_contents())
        obj = self.enums[name]

        print >>cc_file, obj.cxx_def()
        cc_file.close()

    def createEnumParam(self, target, source, env):
        assert len(target) == 1 and len(source) == 1

        hh_file = file(target[0].abspath, 'w')
        name = str(source[0].get_contents())
        obj = self.enums[name]

        print >>hh_file, obj.cxx_decl()

    def buildParams(self, target, source, env):
        names = [ s.get_contents() for s in source ]
        objs = [ self.sim_objects[name] for name in names ]
        out = file(target[0].abspath, 'w')

        ordered_objs = []
        obj_seen = set()
        def order_obj(obj):
            name = str(obj)
            if name in obj_seen:
                return

            obj_seen.add(name)
            if str(obj) != 'SimObject':
                order_obj(obj.__bases__[0])

            ordered_objs.append(obj)

        for obj in objs:
            order_obj(obj)

        enums = set()
        predecls = []
        pd_seen = set()

        def add_pds(*pds):
            for pd in pds:
                if pd not in pd_seen:
                    predecls.append(pd)
                    pd_seen.add(pd)

        for obj in ordered_objs:
            params = obj._params.local.values()
            for param in params:
                ptype = param.ptype
                if issubclass(ptype, self.m5.params.Enum):
                    if ptype not in enums:
                        enums.add(ptype)
                pds = param.swig_predecls()
                if isinstance(pds, (list, tuple)):
                    add_pds(*pds)
                else:
                    add_pds(pds)

        print >>out, '%module params'

        print >>out, '%{'
        for obj in ordered_objs:
            print >>out, '#include "params/%s.hh"' % obj
        print >>out, '%}'

        for pd in predecls:
            print >>out, pd

        enums = list(enums)
        enums.sort()
        for enum in enums:
            print >>out, '%%include "enums/%s.hh"' % enum.__name__
        print >>out

        for obj in ordered_objs:
            if obj.swig_objdecls:
                for decl in obj.swig_objdecls:
                    print >>out, decl
                continue

            code = ''
            base = obj.get_base()

            code += '// stop swig from creating/wrapping default ctor/dtor\n'
            code += '%%nodefault %s;\n' % obj.cxx_class
            code += 'class %s ' % obj.cxx_class
            if base:
                code += ': public %s' % base
            code += ' {};\n'

            klass = obj.cxx_class;
            if hasattr(obj, 'cxx_namespace'):
                new_code = 'namespace %s {\n' % obj.cxx_namespace
                new_code += code
                new_code += '}\n'
                code = new_code
                klass = '%s::%s' % (obj.cxx_namespace, klass)

            print >>out, code

        for obj in ordered_objs:
            print >>out, '%%include "params/%s.hh"' % obj

    def makeSwigInit(self, target, source, env):
        f = file(str(target[0]), 'w')
        print >>f, 'extern "C" {'
        for module in source:
            print >>f, '    void init_%s();' % module.get_contents()
        print >>f, '}'
        print >>f, 'void init_swig() {'
        for module in source:
            print >>f, '    init_%s();' % module.get_contents()
        print >>f, '}'
        f.close()

    def compilePyFile(self, target, source, env):
        '''Action function to compile a .py into a .pyc'''
        py_compile.compile(str(source[0]), str(target[0]))

    def buildPyZip(self, target, source, env):
        '''Action function to build the zip archive.  Uses the
        PyZipFile module included in the standard Python library.'''

        py_compiled = {}
        for s in self.py_sources:
            compname = str(s.compiled)
            assert compname not in py_compiled
            py_compiled[compname] = s

        zf = zipfile.ZipFile(str(target[0]), 'w')
        for s in source:
            zipname = str(s)
            arcname = py_compiled[zipname].arcname
            zf.write(zipname, arcname)
        zf.close()

    def traceFlagsPy(self, target, source, env):
        assert(len(target) == 1)

        f = file(str(target[0]), 'w')

        allFlags = []
        for s in source:
            val = eval(s.get_contents())
            allFlags.append(val)

        print >>f, 'baseFlags = ['
        for flag, compound, desc in allFlags:
            if not compound:
                print >>f, "    '%s'," % flag
        print >>f, "    ]"
        print >>f

        print >>f, 'compoundFlags = ['
        print >>f, "    'All',"
        for flag, compound, desc in allFlags:
            if compound:
                print >>f, "    '%s'," % flag
        print >>f, "    ]"
        print >>f

        print >>f, "allFlags = frozenset(baseFlags + compoundFlags)"
        print >>f

        print >>f, 'compoundFlagMap = {'
        all = tuple([flag for flag,compound,desc in allFlags if not compound])
        print >>f, "    'All' : %s," % (all, )
        for flag, compound, desc in allFlags:
            if compound:
                print >>f, "    '%s' : %s," % (flag, compound)
        print >>f, "    }"
        print >>f

        print >>f, 'flagDescriptions = {'
        print >>f, "    'All' : 'All flags',"
        for flag, compound, desc in allFlags:
            print >>f, "    '%s' : '%s'," % (flag, desc)
        print >>f, "    }"

        f.close()

    def traceFlagsCC(self, target, source, env):
        assert(len(target) == 1)

        f = file(str(target[0]), 'w')

        allFlags = []
        for s in source:
            val = eval(s.get_contents())
            allFlags.append(val)

        # file header
        print >>f, '''
/*
 * DO NOT EDIT THIS FILE! Automatically generated
 */

#include "base/traceflags.hh"

using namespace Trace;

const char *Trace::flagStrings[] =
{'''

        # The string array is used by SimpleEnumParam to map the strings
        # provided by the user to enum values.
        for flag, compound, desc in allFlags:
            if not compound:
                print >>f, '    "%s",' % flag

        print >>f, '    "All",'
        for flag, compound, desc in allFlags:
            if compound:
                print >>f, '    "%s",' % flag

        print >>f, '};'
        print >>f
        print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1)
        print >>f

        #
        # Now define the individual compound flag arrays.  There is an array
        # for each compound flag listing the component base flags.
        #
        all = tuple([flag for flag,compound,desc in allFlags if not compound])
        print >>f, 'static const Flags AllMap[] = {'
        for flag, compound, desc in allFlags:
            if not compound:
                print >>f, "    %s," % flag
        print >>f, '};'
        print >>f

        for flag, compound, desc in allFlags:
            if not compound:
                continue
            print >>f, 'static const Flags %sMap[] = {' % flag
            for flag in compound:
                print >>f, "    %s," % flag
            print >>f, "    (Flags)-1"
            print >>f, '};'
            print >>f

        #
        # Finally the compoundFlags[] array maps the compound flags
        # to their individual arrays/
        #
        print >>f, 'const Flags *Trace::compoundFlags[] ='
        print >>f, '{'
        print >>f, '    AllMap,'
        for flag, compound, desc in allFlags:
            if compound:
                print >>f, '    %sMap,' % flag
        # file trailer
        print >>f, '};'

        f.close()

    def traceFlagsHH(self, target, source, env):
        assert(len(target) == 1)

        f = file(str(target[0]), 'w')

        allFlags = []
        for s in source:
            val = eval(s.get_contents())
            allFlags.append(val)

        # file header boilerplate
        print >>f, '''
/*
 * DO NOT EDIT THIS FILE!
 *
 * Automatically generated from traceflags.py
 */

#ifndef __BASE_TRACE_FLAGS_HH__
#define __BASE_TRACE_FLAGS_HH__

namespace Trace {

enum Flags {'''

        # Generate the enum.  Base flags come first, then compound flags.
        idx = 0
        for flag, compound, desc in allFlags:
            if not compound:
                print >>f, '    %s = %d,' % (flag, idx)
                idx += 1

        numBaseFlags = idx
        print >>f, '    NumFlags = %d,' % idx

        # put a comment in here to separate base from compound flags
        print >>f, '''
// The remaining enum values are *not* valid indices for Trace::flags.
// They are "compound" flags, which correspond to sets of base
// flags, and are used by changeFlag.'''

        print >>f, '    All = %d,' % idx
        idx += 1
        for flag, compound, desc in allFlags:
            if compound:
                print >>f, '    %s = %d,' % (flag, idx)
                idx += 1

        numCompoundFlags = idx - numBaseFlags
        print >>f, '    NumCompoundFlags = %d' % numCompoundFlags

        # trailer boilerplate
        print >>f, '''\
}; // enum Flags

// Array of strings for SimpleEnumParam
extern const char *flagStrings[];
extern const int numFlagStrings;

// Array of arraay pointers: for each compound flag, gives the list of
// base flags to set.  Inidividual flag arrays are terminated by -1.
extern const Flags *compoundFlags[];

/* namespace Trace */ }

#endif // __BASE_TRACE_FLAGS_HH__
'''

        f.close()
