# -*- mode:python -*-

# Copyright (c) 2004-2005 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.

import os, os.path, re, sys

Import('env')

import scons_helper

def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
    if isinstance(source, str):
        source = file(source, 'r')

    if isinstance(target, str):
        target = file(target, 'w')

    print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \
          (`path`, `name`, `ext`, `filename`)

    for line in source:
        line = line
        # escape existing backslashes
        line = line.replace('\\', '\\\\')
        # escape existing triple quotes
        line = line.replace("'''", r"\'\'\'")

        print >>target, line,

    print >>target, "''')"
    print >>target

def WriteCFile(target, source, name):
    if isinstance(source, str):
        source = file(source, 'r')

    if isinstance(target, str):
        target = file(target, 'w')

    print >>target, 'const char %s_string[] = {' % name

    count = 0
    from array import array
    try:
        while True:
            foo = array('B')
            foo.fromfile(source, 10000)
            l = [ str(i) for i in foo.tolist() ]
            count += len(l)
            for i in xrange(0,9999,20):
                print >>target, ','.join(l[i:i+20]) + ','
    except EOFError:
        l = [ str(i) for i in foo.tolist() ]
        count += len(l)
        for i in xrange(0,len(l),20):
            print >>target, ','.join(l[i:i+20]) + ','
        print >>target, ','.join(l[i:]) + ','

    print >>target, '};'
    print >>target, 'const int %s_length = %d;' % (name, count)
    print >>target

def splitpath(path):
    dir,file = os.path.split(path)
    path = []
    assert(file)
    while dir:
        dir,base = os.path.split(dir)
        path.insert(0, base)
    return path, file

def MakeEmbeddedPyFile(target, source, env):
    target = file(str(target[0]), 'w')
   
    tree = {}
    for src in source:
        src = str(src)
        path,pyfile = splitpath(src)
        node = tree
        for dir in path:
            if not node.has_key(dir):
                node[dir] = { }
            node = node[dir]

        name,ext = pyfile.split('.')
        if name == '__init__':
            node['.hasinit'] = True
        node[pyfile] = (src,name,ext,src)

    done = False
    while not done:
        done = True
        for name,entry in tree.items():
            if not isinstance(entry, dict): continue
            if entry.has_key('.hasinit'): continue

            done = False
            del tree[name]
            for key,val in entry.iteritems():
                if tree.has_key(key):
                    raise NameError, \
                          "dir already has %s can't add it again" % key
                tree[key] = val

    files = []
    def populate(node, path = []):
        names = node.keys()
        names.sort()
        for name in names:
            if name == '.hasinit':
                continue
            
            entry = node[name]
            if isinstance(entry, dict):
                if not entry.has_key('.hasinit'):
                    raise NameError, 'package directory missing __init__.py'
                populate(entry, path + [ name ])
            else:
                pyfile,name,ext,filename = entry
                files.append((pyfile, path, name, ext, filename))
    populate(tree)

    for pyfile, path, name, ext, filename in files:
        WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename)

def MakeDefinesPyFile(target, source, env):
    f = file(str(target[0]), 'w')
    print >>f, "import __main__"
    print >>f, "__main__.m5_build_env = ",
    print >>f, source[0]
    f.close()

CFileCounter = 0
def MakePythonCFile(target, source, env):
    global CFileCounter
    target = file(str(target[0]), 'w')

    print >>target, '''\
#include "base/embedfile.hh"

namespace {
'''
    for src in source:
        src = str(src)
        fname = os.path.basename(src)
        name = 'embedded_file%d' % CFileCounter
        CFileCounter += 1
        WriteCFile(target, src, name)
        print >>target, '''\
EmbedMap %(name)s("%(fname)s",
    %(name)s_string, %(name)s_length);

''' % locals()
    print >>target, '''\

/* namespace */ }
'''

# base list of .py files to embed
embedded_py_files = [ '../util/pbs/jobfile.py' ]
# add all .py files in python/m5 
objpath = os.path.join(env['SRCDIR'], 'python', 'm5')
for root, dirs, files in os.walk(objpath, topdown=True):
    for i,dir in enumerate(dirs):
        if dir == 'SCCS':
            del dirs[i]
            break

    assert(root.startswith(objpath))
    for f in files:
        if f.endswith('.py'):
            embedded_py_files.append(os.path.join(root, f))

embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh')

optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions])
env.Command('defines.py', Value(optionDict), MakeDefinesPyFile)

env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile)
env.Depends('embedded_py.cc', embedfile_hh)
env.Command('embedded_py.cc',
            ['string_importer.py', 'defines.py', 'embedded_py.py'],
            MakePythonCFile)
