#
# Licensed 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. See accompanying LICENSE file.
#

import os
import re
import sys
import errno
import shlex
import logging
import subprocess
import platform
import fileinput
import getpass
import shutil
from xml.etree import ElementTree as ET
from os.path import basename
from subprocess import Popen,PIPE
from datetime import date
from datetime import datetime

os_name = platform.system()
os_name = os_name.upper()

if os_name == "LINUX":
        RANGER_ADMIN_HOME = os.getenv("RANGER_ADMIN_HOME")
        if RANGER_ADMIN_HOME is None:
                RANGER_ADMIN_HOME = os.getcwd()
elif os_name == "WINDOWS":
        RANGER_ADMIN_HOME = os.getenv("RANGER_ADMIN_HOME")

def log(msg,type):
        if type == 'info':
                logging.info(" %s",msg)
        if type == 'debug':
                logging.debug(" %s",msg)
        if type == 'warning':
                logging.warning(" %s",msg)
        if type == 'exception':
                logging.exception(" %s",msg)
        if type == 'error':
                logging.error(" %s",msg)

def username_validation(username):
        if username:
                if re.search("[\\\`'\"]",username):
                        log("[E] username contains one of the unsupported special characters like \" ' \ `","error")
                        sys.exit(1)


def main(argv):
        FORMAT = '%(asctime)-15s %(message)s'
        logging.basicConfig(format=FORMAT, level=logging.DEBUG)
        ews_lib = os.path.join(RANGER_ADMIN_HOME,"ews","lib")
        app_home = os.path.join(RANGER_ADMIN_HOME,"ews","webapp")
        ranger_log = os.path.join(RANGER_ADMIN_HOME,"ews","logs")

        if os.environ['JAVA_HOME'] == "":
                log("[E] ---------- JAVA_HOME environment property not defined, aborting installation. ----------", "error")
                sys.exit(1)
        JAVA_BIN=os.path.join(os.environ['JAVA_HOME'],'bin','java')
        if os_name == "WINDOWS" :
                JAVA_BIN = JAVA_BIN+'.exe'
        if os.path.isfile(JAVA_BIN):
                pass
        else:
                while os.path.isfile(JAVA_BIN) == False:
                        log("Enter java executable path: :","info")
                        JAVA_BIN=raw_input()
        log("[I] Using Java:" + str(JAVA_BIN),"info")

        USERNAME = ''
        OLD_PASSWORD = ''
        NEW_USERNAME=''

        if len(argv)==4:
                userName=argv[1]
                oldPassword=argv[2]
                newUserName=argv[3]
        else:
                log("[E] Invalid argument list.", "error")
                log("[I] Usage : python changeusernameutil.py <loginID> <currentPassword> <newUserName>","info")
                sys.exit(1)

        while userName == "":
                print "Enter user name:"
                userName=raw_input()

        while oldPassword == "":
                oldPassword=getpass.getpass("Enter current password:")

        while newUserName == "":
                newUserName=getpass.getpass("Enter new user name:")

        if userName==newUserName:
                log("[E] Old User Name and New User Name argument are same. Exiting!!", "error")
                sys.exit(1)

        if userName != "" and oldPassword != "" and newUserName != "":
                username_validation(newUserName)
                if os_name == "LINUX":
                        path = os.path.join("%s","WEB-INF","classes","conf:%s","WEB-INF","classes","lib","*:%s","WEB-INF",":%s","META-INF",":%s","WEB-INF","lib","*:%s","WEB-INF","classes",":%s","WEB-INF","classes","META-INF:%s/*")%(app_home ,app_home ,app_home, app_home, app_home, app_home ,app_home,ews_lib)
                elif os_name == "WINDOWS":
                        path = os.path.join("%s","WEB-INF","classes","conf;%s","WEB-INF","classes","lib","*;%s","WEB-INF",";%s","META-INF",";%s","WEB-INF","lib","*;%s","WEB-INF","classes",";%s","WEB-INF","classes","META-INF" )%(app_home ,app_home ,app_home, app_home, app_home, app_home ,app_home)
                get_java_cmd = "%s -Dlogdir=%s -Dlog4j.configuration=db_patch.log4j.xml -cp %s org.apache.ranger.patch.cliutil.%s %s %s %s"%(JAVA_BIN,ranger_log,path,'ChangeUserNameUtil',userName,oldPassword,newUserName)
                if os_name == "LINUX":
                        ret = subprocess.call(shlex.split(get_java_cmd))
                elif os_name == "WINDOWS":
                        ret = subprocess.call(get_java_cmd)
                if ret == 0:
                        log("[I] User name updated successfully","info")
                else:
                        log("[E] Unable to update user name of user:"+userName,"error")
                        sys.exit(1)
        else:
                log("[E] Input Error","error")

main(sys.argv)
