#!/usr/bin/env python
############################################################################
#  
#  Copyright (c)2000 Fourthought, Inc.
#  http://ftsuite.com/4ODS
#
############################################################################
#
# File Name: 		init.py
#
# Documentation:	http://docs.ftsuite.com/4ODS/Tools/4odb_create.py.html
#


#Create a new database ready to accept ODL

import string, os, re
from Ft.Ods.Parsers.Odl import Processor

__doc__  = """Initialize/update a 4ODS database and generate pstub classes."""

_define_re = re.compile(r'(?P<name>[a-zA-Z_][\w_]*)(=(?P<value>.*))?')

def Run(options, args):

    from Ft.Ods.StorageManager import Adapters
    database = args['database']
    Adapters.g_driverName = options.get('adapter')

    # Verify that the specified file(s) exist
    for file in args['file']:
        if file != '-' and not os.path.isfile(file):
            raise SystemExit("'%s' does not exist" % file)

    if options.has_key('init'):
        if not options.has_key('force'):
            print "WARNING: This will destroy all data in database '%s'!" % database
            answer = ''
            while answer not in ['y', 'n', 'yes', 'no']:
                answer = string.lower(raw_input('Are you sure (yes/no)? '))
            if answer not in ['y', 'yes']:
                return

        # Create the database
        from Ft.Ods.Tools import destroy,create
        try:
            destroy.Run(options,{'dbName' : database})
        except:
            pass
        create.Run(options,{'dbName' : database})

    includes = options.get('include', [])
    if type(includes) is not type([]):
        includes = [includes]

    defs = options.get('define')
    defines = {}

    if defs is not None:
        if type(defs) is not type([]):
            defs = [defs]

        for define in defs:
            match = _define_re.match(define)
            if match:
                defines[match.group('name')] = match.group('value') or 1
    
    processor = Processor.Processor(database,
                                    options.get('package'),
                                    options.get('directory'),
                                    includes,
                                    defines,
                                    preprocessonly=options.has_key('preprocess'))

    if options.has_key('extension'):
        extensions = options['extension']
        if type(extensions) != type([]):
            extensions = [extensions]
        import register
        register._Run(database,extensions)
        
    for file in args['file']:
        if file == '-':
            stream = sys.stdin
        else:
            stream = open(file)
        processor.run(stream)
    return


def Register():
    from Ft.Lib.CommandLine import Options, Command, Arguments
    from Ft.Lib.CommandLine.Options import *
    from Ft.Lib.CommandLine.Arguments import *

    args = [RequiredArgument('database',
                             'The name of the database.',
                             str),
            OneOrMoreArgument('file',
                              'The ODMG ODL file(s) to compile',
                              str),
            ]

    opts = Options([
        Option('p', 'package=path',
               'Use path as the Python path for the pstubs'),
        Option('d', 'directory=dir',
               'Write pstubs to the specified directory'),
        ExclusiveOptions([Option('i', 'init',
                                 'Initialize the specified database'),
                          Option('u', 'update',
                                 'Update an existing database'),
                          ]),
        Option('f', 'force',
               'Disable prompting'),
        Option('D', 'define=name[=value]',
               'Define name for the preprocessor'),
        Option('I', 'include=dir',
               'Include dir in the preprocessor search path'),
        Option('E', 'preprocess',
               'Only run the preprocessor, sending its output to stdout'),
        Option('e', 'extension=',
               'The python path to an extension module.'),
        ])

    cmd = Command.Command('init',
                          'Initial a 4ODS database',
                          ' test -ifg test.odl',
                          __doc__,
                          function=Run,
                          arguments=args,
                          options=opts,
                          )
    return cmd
