#!/bin/env python
# newSapdbSrc.py

import sys
import os
import string
import re
from UserDict import UserDict

def addPythonLib ():
    toolLib = os.path.normpath (os.path.join (sys.path [0], '..', 'lib/Python'))
    sys.path.insert (1, toolLib)

addPythonLib ()

def fatalError (msg):
    sys.stderr.write ('newSapdbSrc: ' + msg + '\n')
    sys.exit (2)

def getOutfile (output, defaultName):
    if os.path.isdir (output):
        output = os.path.join (output, defaultName)
    return output

class RexReplace (UserDict):
    def replaceMatch (self, match):
        return self [match.group (0)]

def findInPath (fname):
    path = os.environ ['PATH']
    for dirname in string.split (path, os.pathsep):
        fullPath = os.path.join (dirname, fname)
        if os.path.exists (fullPath):
            return dirname
    return ''


def smartExists (base, file):
    if type (file) == type (''):
        return os.path.exists (os.path.join (base, file))
    else:
        for fname in file:
            if os.path.exists (os.path.join (base, fname)):
                return 1
        return None

def findPythonIncludes ():
    result = 'NO'
    for dirname in ['/usr/include/python']:
        requiredFiles = ['Python.h', ['config.h', 'pyconfig.h']]
        for file in requiredFiles:
            if not smartExists (dirname, file):
                break
        return dirname
    return result

_releaseFileName = 'sys/src/sp/gsp100.h'

def findReleaseFile (vmakePath):
    for dirname in vmakePath:
        fullPath = os.path.join (dirname, _releaseFileName)
        if os.path.exists (fullPath):
            return fullPath
    return None

def createVMakePath (args):
    if len (args) == 0:
        fatalError ('must specify at least one source directory')
    # find release file
    releaseFile = findReleaseFile (args)
    if releaseFile is None:
        fatalError ('no directory contained ' + _releaseFileName)
    # make all absolute
    vmakePath = map (os.path.abspath, args)
    # create non existent directories
    if not os.path.exists (vmakePath [0]):
        os.mkdir (vmakePath [0])
    #
    return vmakePath

def getReleaseInfo (vmakePath):
    releaseFile = findReleaseFile (vmakePath)
    source = open (releaseFile, 'r').read ()
    result = []
    for name in ['MAJOR_VERSION_NO_SP100', 'MINOR_VERSION_NO_SP100',
            'CORRECTION_LEVEL_SP100', 'BUILD_PREFIX_SP100']:
        match = re.search (r'#\s*define\s+' + name + r'\s+(\d+)', source)
        if match is None:
            fatalError ('invalid release info in ' + releaseFile)
        result.append (match.group (1))
    return result

def fillTemplate (options, vmakePath):
    releaseInfo = getReleaseInfo (vmakePath)
    tool = os.path.abspath (os.path.normpath (os.path.join (sys.path [0], '..')))
    # get template
    templateFile = os.path.join (tool, 'data', 'distribTools', 'iprofile')
    if not os.path.exists (templateFile):
        fatalError ('Cannot find ' + templateFile)
    source = open (templateFile, 'r').read ()
    # build dict
    replacements = RexReplace ({
        '§DEVTOOL': tool,
        '§MAJ':  releaseInfo [0],
        '§MIN':  releaseInfo [1],
        '§COR':  releaseInfo [2],
        '§BLDPRFX': releaseInfo [3],
        '§DEV':  vmakePath [0],
        '§ORG':  string.join (vmakePath [1:], ','),
        '§PYTHON': options.python,
        '§PYINCL': options.pyinclude,
        '§EDITOR': options.editor,
    })
    # replace values
    filled = re.sub ('§[A-Za-z+]+', replacements.replaceMatch, source)
    # write
    iprofile = os.path.join (vmakePath [0], '.iprofile')
    open (iprofile, 'w').write (filled)

def writeInitScript (options, vmakePath):
    initScript = getOutfile (options.output, 'devsapdb')
    stream = open (initScript, 'w')
    stream.write ('# script to init the SAP DB developpment environment\n')
    stream.write ('cd ' + vmakePath [0] + '\n')
    stream.write ('. .iprofile\n')
    stream.close ()
    print "execute . " + initScript + ' to start SAP DB development'

def newSapdbSrc (options, args):
    vmakePath = createVMakePath (args)
    fillTemplate (options, vmakePath)
    writeInitScript (options, vmakePath)

def main (options, args):
    """initialize a new SAP DB development source tree

    All command line arguments are directories to be used to search
    for sources, at least one must contain a file sys/src/sp/gsp100.h.

    If the first directory doesn't exist, it will be created

    """
    newSapdbSrc (options, args)

def _options ():
    return [
        # (optstring, varname, typechar, default, help)
        ('python', None, ':', findInPath ('python'), 'path to python executable'),
        ('pyinclude', None, ':', findPythonIncludes (), 'path to Python include files'),
        ('editor', None, ':', 'vi', 'default editor'),
        ('o', 'output', ':', 'devsapdb', 'name of script to init dev environment'),
        ]

if __name__ == '__main__':
    import optlib
    optlib.optMain2 (main, _options ())

