#!/usr/bin/env python
# -----------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# -----------------------------------------------------------------------


import os
import sys
import getopt

import shutil
import subprocess
from  stat import *

import string
import random

from ducc_util import DuccUtil

from ducc_base import Properties
from ducc_base import Property

from ducc_base import find_ducc_home
from ducc_base import find_localhost

from ducc import Ducc

import db_util as dbu

# 
# Create and initialize the DUCC database.  In a new installation this is handled by
# ducc_post_install.  Older installations need to run db_create as one of the steps
# of migration to the DB.
#
class DbCreate(DuccUtil):

    def usage(self, msg):

        if ( msg != None ):
            print ' '.join(msg)

              
        print 'DbCreate configures the database and installs the schema.'
        print ''
        print "Usage:"
        print "   db_create [options]"
        print "        If no options defaults are used for expected parameters."
        print ""
        print "Options:"
        print "   [-d, --db-password] <root password for database>"
        print "        This is the password DUCC uses to manage the database."
        print ""
        print "   [-h, -? --help]"
        print "        Prints this message."
        print ""
        sys.exit(1) 
                                    
    def main(self, argv):                    

        self.database_pw = None

        try:
            opts, args = getopt.getopt(argv, 'd:n:h?', ['db-password=', 'help'])
        except:
            self.usage("Invalid arguments " + ' '.join(argv))


        for ( o, a ) in opts:
            if o in ('-d', '--db-password'):
                self.database_pw = a
            elif o in ('-h', '-?', '--help'):
                self.usage(None)
        

        if ( self.database_pw == None ):
            self.database_pw = self.generate_pw()

        # start with merged properties
        self.merge_properties();

        # configure the database for local system and initialize the schema
        db_node = self.ducc_properties.get("ducc.head")
        if ( dbu.configure_database(self.DUCC_HOME, db_node, self.jvm, self.database_pw)):
            private_props_name = self.DUCC_HOME + '/resources.private/ducc.private.properties'

            print 'Writing database password to', private_props_name
            ducc_site_properties = Properties();
            site_props_name = self.DUCC_HOME + '/resources/site.ducc.properties'
            ducc_site_properties.load(site_props_name)
            ducc_site_properties.put('ducc.database.host', db_node);
            ducc_site_properties.put('ducc.service.persistence.impl', 'org.apache.uima.ducc.database.StateServicesDb'   , ['# Service manager persistence'])
            ducc_site_properties.put('ducc.job.history.impl'        , 'org.apache.uima.ducc.database.HistoryManagerDb'  , ['# History and checkpoint'])
            ducc_site_properties.put('ducc.rm.persistence.impl'     , 'org.apache.uima.ducc.database.RmStatePersistence', ['# RM state persistence'])

            # if we don't die before this we need to enable db in site.ducc.properties and set the
            # db password into resources.private/ducc.private.properties
            ducc_site_properties.write(site_props_name)

            private_props_name = self.DUCC_HOME + '/resources.private/ducc.private.properties'
            private_properties = Properties()
            private_properties.load(private_props_name)
            private_properties.delete('db_password')
            private_properties.put('db_password', self.database_pw, ['#Db password, default is randomly generated']);
            private_properties.write(private_props_name)

        # remerge to insure it's all correct and ready to go
        self.merge_properties();
    
    # generate a random string between 8 and 16 characters long
    def generate_pw(self):
        pwlen = random.randrange(8,16)
        reply = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(pwlen)])
        return reply
        
if __name__ == "__main__":

    postinstall = DbCreate()
    postinstall.main(sys.argv[1:])
