#!/usr/bin/python
# -*- coding: utf-8 -*-

# 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 subprocess
import glob
from random import choice
import string
from optparse import OptionParser
import commands
import shutil

# squelch mysqldb spurious warnings
import warnings
warnings.simplefilter('ignore')
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
# ---- We do this so cloud_utils can be looked up in the following order:
# ---- 1) Sources directory
# ---- 2) waf configured PYTHONDIR
# ---- 3) System Python path
for pythonpath in (
        "@PYTHONDIR@",
        os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
    ):
        if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
# ---- End snippet of code ----

def runCmd(cmds):
    process = subprocess.Popen(' '.join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    if process.returncode != 0:
        raise Exception(stderr)
    return stdout

class DBDeployer(object):
    parser = None
    options = None
    args = None
    isDebug = False
    mgmtsecretkey = None
    dbsecretkey = None
    encryptiontype = None
    dbConfPath = r"@MSCONF@"
    dbDotProperties = {}
    dbDotPropertiesIndex = 0
    encryptionKeyFile = '@MSCONF@/key'
    encryptionJarPath = '@COMMONLIBDIR@/lib/jasypt-1.9.0.jar'
    success = False
    magicString = 'This_is_a_magic_string_i_think_no_one_will_duplicate'

    def preRun(self):
        def backUpDbDotProperties():
            dbpPath = os.path.join(self.dbConfPath, 'db.properties')
            copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
            
            if os.path.isfile(dbpPath):
                shutil.copy2(dbpPath, copyPath)
        
        backUpDbDotProperties()
    
    def postRun(self):
        def cleanOrRecoverDbDotProperties():
            dbpPath = os.path.join(self.dbConfPath, 'db.properties')
            copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
            if os.path.isfile(copyPath):
                if not self.success:
                    shutil.copy2(copyPath, dbpPath)
                os.remove(copyPath)
        
        cleanOrRecoverDbDotProperties()
                
        
    def info(self, msg, result=None):
        output = ""
        if msg is not None:
            output = "%-80s"%msg
            
        if result is True:
            output += "[ \033[92m%-2s\033[0m ]\n"%"OK"
        elif result is False:
            output += "[ \033[91m%-6s\033[0m ]\n"%"FAILED"
        sys.stdout.write(output)
        sys.stdout.flush()
    
    def debug(self, msg):
        msg = "DEBUG:%s"%msg
        sys.stdout.write(msg)
        sys.stdout.flush()

    def putDbProperty(self, key, value):
        if self.dbDotProperties.has_key(key):
            (oldValue, index) = self.dbDotProperties[key]
            self.dbDotProperties[key] = (value, index)
        else:
            self.dbDotProperties[key] = (value, self.dbDotPropertiesIndex)
            self.dbDotPropertiesIndex += 1
    
    def getDbProperty(self, key):
        if not self.dbDotProperties.has_key(key):
            return None
        (value, index) = self.dbDotProperties[key]
        return value
        
    def errorAndExit(self, msg):
        self.postRun()
        err = '''\n\nWe apologize for below error:
***************************************************************      
%s
*************************************************************** 
Please run:

    cloud-setup-encryption -h

for full help
''' % msg
        sys.stderr.write(err)
        sys.stderr.flush()
        sys.exit(1)

    def prepareDBFiles(self):
        def prepareDBDotProperties():
            dbpPath = os.path.join(self.dbConfPath, 'db.properties')
            dbproperties = file(dbpPath).read().splitlines()
            newdbp = []
            emptyLine = 0
            for line in dbproperties:
                passed = False
                line = line.strip()
                if line.startswith("#"): key = line; value = ''; passed = True
                if line == '' or line == '\n': key = self.magicString + str(emptyLine); value = ''; emptyLine += 1; passed = True
                
                try:
                    if not passed:
                        (key, value) = line.split('=', 1)
                except Exception, e:
                    err = '''Wrong format in %s (%s):
Besides comments beginning "#" and empty line, all key-value pairs must be in formula of
                    key=value
for example:
                    db.cloud.username = cloud
                    ''' % (dbpPath, line)
                    self.errorAndExit(err)
                self.putDbProperty(key, value)
            self.info("Preparing %s"%dbpPath, True)
        
        prepareDBDotProperties()    
    
    def finalize(self):
        def finalizeDbProperties():
            entries = []
            for key in self.dbDotProperties.keys():
                (value, index) = self.dbDotProperties[key]
                if key.startswith("#"):
                    entries.insert(index, key)
                elif key.startswith(self.magicString):
                    entries.insert(index, '')
                else:
                    entries.insert(index, "%s=%s"%(key, value))
            file(os.path.join(self.dbConfPath, 'db.properties'), 'w').write('\n'.join(entries))
        
        self.info("Finalizing setup ...", None)
        finalizeDbProperties()
        self.info(None, True)
        self.success = True # At here, we have done successfully and nothing more after this flag is set
                        
    def processEncryptionStuff(self):
        def encrypt(input):
            cmd = ['java','-classpath',self.encryptionJarPath,'org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI', 'encrypt.sh', 'input=\'%s\''%input, 'password=%s'%self.mgmtsecretkey,'verbose=false']
            return runCmd(cmd).strip('\n')
        
        def saveMgmtServerSecretKey():
            if self.encryptiontype == 'file':
                file(self.encryptionKeyFile, 'w').write(self.mgmtsecretkey)
                
        def formatEncryptResult(value):
            return 'ENC(%s)'%value
        
        def encryptDBSecretKey():
            self.putDbProperty('db.cloud.encrypt.secret', formatEncryptResult(encrypt(self.dbsecretkey)))
        
        def encryptDBPassword():
            dbPassword = self.getDbProperty('db.cloud.password')       
            if dbPassword == '': return # Don't encrypt empty password
            if dbPassword == None: self.errorAndExit('Cannot find db.cloud.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
            self.putDbProperty('db.cloud.password', formatEncryptResult(encrypt(dbPassword)))
            
            usagePassword = self.getDbProperty('db.usage.password')
            if usagePassword == '': return # Don't encrypt empty password
            if usagePassword == None: self.errorAndExit('Cannot find db.usage.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
            self.putDbProperty('db.usage.password', formatEncryptResult(encrypt(usagePassword)))
        
        self.info("Processing encryption ...", None)
        self.putDbProperty("db.cloud.encryption.type", self.encryptiontype)
        saveMgmtServerSecretKey()
        encryptDBSecretKey()
        encryptDBPassword()
        self.info(None, True)
        
    def parseOptions(self):
        def parseOtherOptions():                     
            self.encryptiontype = self.options.encryptiontype
            self.mgmtsecretkey = self.options.mgmtsecretkey
            self.dbsecretkey = self.options.dbsecretkey
            self.isDebug = self.options.debug
            
            
        def validateParameters():
            if self.encryptiontype != 'file' and self.encryptiontype != 'web':
                self.errorAndExit('Wrong encryption type %s, --encrypt-type can only be "file" or "web'%self.encryptiontype)
            
    #---------------------- option parsing and command line checks ------------------------
        usage = """%prog [-e ENCRYPTIONTYPE] [-m MGMTSECRETKEY] [-k DBSECRETKEY] [--debug]
    
    This command sets up the CloudStack Encryption.    
    
    """
        self.parser = OptionParser(usage=usage)
        self.parser.add_option("-v", "--debug", action="store_true", dest="debug", default=False,
                          help="If enabled, print the commands it will run as they run")
        self.parser.add_option("-e", "--encrypt-type", action="store", type="string", dest="encryptiontype", default="file",
                          help="Encryption method used for db password encryption. Valid values are file, web. Default is file.")
        self.parser.add_option("-m", "--managementserver-secretkey", action="store", type="string", dest="mgmtsecretkey", default="password",
                          help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password")
        self.parser.add_option("-k", "--database-secretkey", action="store", type="string", dest="dbsecretkey", default="password",
                          help="Secret key used to encrypt sensitive database values. A string, default is password")
        
        (self.options, self.args) = self.parser.parse_args()
        parseOtherOptions()
        validateParameters()
    
    def run(self):
        try:
            self.preRun()
            self.parseOptions()
            self.prepareDBFiles()            
            self.processEncryptionStuff()
            self.finalize()
        finally:
            self.postRun()
        
        print ''
        print "CloudStack has successfully setup Encryption"
        print ''

if __name__ == "__main__":
   o = DBDeployer()
   o.run()
        
