#!/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.cmd_name_nodetool = 'nodetool'
        
        self.database_automanage = True
        self.database_host_list = None
        self.database_user = None
        self.database_pw = None

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


        for ( o, a ) in opts:
            if o in ('-a', '--db-automanage'):
            	if(o in { 'True', 'T', 'true', 't'}):
                    self.database_automanage = True
                else:
                    self.database_automanage = False
            if o in ('-o', '--db-host-list'):
                self.database_host_list = a
            if o in ('-u', '--db-user'):
                self.database_user = a
            if o in ('-d', '--db-password'):
                self.database_pw = a
            elif o in ('-h', '-?', '--help'):
                self.usage(None)
        
 
        	
        # abort db create if db already running
        status = 'unknown'
        cmd = self.DUCC_HOME+'/cassandra-server/bin/nodetool'
        p = subprocess.Popen([cmd, 'info'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = p.communicate()
        if ((err != None) and (err != '')):
            if (err.startswith(self.cmd_name_nodetool+': Failed to connect')):
                status = 'down'
        elif ((out != None) and (out != '')):
            for line in out.splitlines():
                if(line.startswith('Uptime')):
                    status = 'up'
                    break
        if(status != 'down'):
            print 'unsafe to proceed, database status: '+status
            return
    
        if( self.database_host_list == None ) :
        	self.database_host_list = self.ducc_properties.get("ducc.database.host.list")
        if( self.database_host_list == None ) :
        	self.database_host_list = self.ducc_properties.get("ducc.database.host")
        if( self.database_host_list == None ) :
        	self.database_host_list = self.ducc_properties.get("ducc.head")
    
    	if ( self.database_user == None ):
            self.database_user = 'ducc'
    
        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, self.ducc_head, self.jvm, self.database_automanage, self.database_host_list, self.database_user, db_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.automanage', str(self.database_automanage));
            ducc_site_properties.delete('ducc.database.host');
            ducc_site_properties.put('ducc.database.host.list', self.database_host_list);
            ducc_site_properties.put('ducc.database.user', self.database_user);
            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__":

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