package com.bmc.arsys.demo.javadriver;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import com.bmc.arsys.api.ARException;
import com.bmc.arsys.api.ARServerUser;
import com.bmc.arsys.api.Constants;
import com.bmc.arsys.api.Field;
import com.bmc.arsys.api.FieldCriteria;
import com.bmc.arsys.api.FieldKey;
import com.bmc.arsys.api.Form;
import com.bmc.arsys.api.FormCriteria;
import com.bmc.arsys.api.IndexInfo;
import com.bmc.arsys.api.SQLResult;
import com.bmc.arsys.api.ServerInfoMap;
import com.bmc.arsys.api.StatusInfo;
import com.bmc.arsys.api.Value;
import com.bmc.arsys.utils.ARConstantsBase;


public class OracleFunctionalIndexHelper extends JavaDriver {
    static OutputWriter outputWriter = new OutputWriter();
    ARServerUser arServerUser;
    ArrayList<String> schemaNames; 
    ArrayList<String> functionalIndexes;
    ArrayList<String> regularIndexes;
    private static final int COMMAND_OPTION_ADD_INDEX = 0;
    private static final int COMMAND_OPTION_DROP_INDEX = 1;
    private static final int COMMAND_OPTION_VIEW_INDEX = 2;
    private static final int COMMAND_OPTION_QUIT_APP = 3;
    private static final int COMMAND_OPTION_MAX_USED = 3;
    private static final int COMMAND_OPTION_REGULAR_INDEX = 0;
    private static final int COMMAND_OPTION_FUNCTIONAL_INDEX = 1;
 

    public OracleFunctionalIndexHelper() {
        initThreadControlBlockPtr();
        schemaNames = new ArrayList<String>();
        functionalIndexes = new ArrayList<String>();
        regularIndexes = new ArrayList<String>();
    }
    
    public int getSchemaCount() {
        return schemaNames.size();
    }    

    void readSchemaNames(String fileName) throws ARException, FileNotFoundException, IOException {
        if ((fileName == null) || (fileName.length() == 0)) {
            //Get all the forms on server 
            schemaNames = (ArrayList<String>) arServerUser.getListForm((long) 0);
        } else {
            populateSchemaNamesFromFile(fileName);
        }
        return;
    }

    private int getSchemaIdForSchema( String schemaName)  throws ARException
    {
        /* Verify that the form name has been specified in proper case */
      //Get all the user managed index associated with the schema
        FormCriteria criteria = new FormCriteria();
        criteria.setPropertiesToRetrieve(FormCriteria.SCHEMA_TYPE);
        Form curForm = arServerUser.getForm(schemaName, criteria);
        if (curForm == null)
            new ARException(2, 303, schemaName);
        int schemaId = 0;
        StringBuilder sqlCommand = new StringBuilder("SELECT schemaId from arschema where name='" + schemaName +"'");
            SQLResult result = arServerUser.getListSQL(sqlCommand.toString(), 1, false);
            if (result == null){
            	throw new ARException(2, 303, schemaName); 
            }
            
            List<List<Value>> valueListList = result.getContents();
            if (valueListList == null || valueListList.size() == 0){
            	throw new ARException(2, 303, schemaName);
            }
            
            schemaId = valueListList.get(0).get(0).getIntValue();
            if (schemaId == 0){
            	throw new ARException(2, 303, schemaName);
            }
        return schemaId;
    }
    private void populateSchemaNamesFromFile(String fileName) throws FileNotFoundException, IOException {
        JavaDriver.getThreadControlBlockPtr().setCurrentInputFile(fileName);
        String inputLine = null;
        BufferedReader currentInputFile = JavaDriver.getThreadControlBlockPtr().getCurrentInputFile();
        inputLine = currentInputFile.readLine();
        while (inputLine != null) {
            /* Remove any trailing white spaces */
            int index = 0;
            for (index = inputLine.length() - 1; index >= 0; index--) {
                if ((inputLine.charAt(index) != ' ') || (inputLine.charAt(index) != '\t')
                        || (inputLine.charAt(index) != '\n')) {
                    break;
                }
            }

            /* Process if it is a comment */
            if ((inputLine.length() >= 1) && (inputLine.charAt(0) == '#')) {
                continue;
            }
            schemaNames.add((String) inputLine);
            inputLine = currentInputFile.readLine();
        }
        JavaDriver.getThreadControlBlockPtr().closeCurrentInputFile();
    }  
  
    void createDBIndexes(String nlsSortParam) {
        String curSchema = null;
        for (int i = 0; i < schemaNames.size(); ++i) {
            curSchema = schemaNames.get(i);
            if (curSchema != null) {
                outputWriter.printHeader("", "Currently processing Form " + curSchema + "...", "\n");
                try {
                    /* Process all the indexes associated with the current schema */
                    createDBIndexesForSchema(curSchema, nlsSortParam);
                    
                } catch (ARException ex) {
                    outputWriter.printHeader("", "Error while processing schema " + curSchema + ".", "\n"); 
                    outputWriter.printHeader("", "Error message " + ex.getMessage() + ".", "\n");
                }
            }
        }
        return;
    }

    void dropDBIndexes(boolean functionalIndex) {
        String curSchema = null;
        for (int i = 0; i < schemaNames.size(); ++i) {
            curSchema = schemaNames.get(i);
            if (curSchema != null) {
                outputWriter.printHeader("", "Currently processing Form " + curSchema + "...", "\n");
                try {
                    /* Process all the indexes associated with the current schema */
                    dropDBIndexesForSchema(curSchema, functionalIndex);
                    
                } catch (ARException ex) {
                    outputWriter.printHeader("", "Error while processing schema " + curSchema + ".", "\n"); 
                    outputWriter.printHeader("", "Error message " + ex.getMessage() + ".", "\n");
                }
            }
        }
        return;
    }
    
    void viewDBIndexes() {     
        String curSchema = null;
        for (int i = 0; i < schemaNames.size(); ++i) {
            curSchema = schemaNames.get(i);
            if (curSchema != null) {
                outputWriter.printHeader("\n", "Currently processing Form " + curSchema + "...", "\n");
                try {
                    /* Process all the indexes associated with the current schema */
                    viewDBIndexesForSchema(curSchema);
                    
                } catch (ARException ex) {
                    outputWriter.printHeader("", "Error while processing schema " + curSchema + ".", "\n"); 
                    outputWriter.printHeader("", "Error message " + ex.getMessage() + ".", "\n");
                }
            }
        }
        return;
    }

    void viewDBIndexesForSchema(String schemaName) throws ARException {       
        int schemaId = getSchemaIdForSchema(schemaName);
        if (schemaId == 0)
        {
            outputWriter.printHeader("", "Error while retrieving schema id for schema " + schemaName + ".", "\n");
            return; 
        }
        retrieveExistingIndexes(schemaId);
        outputWriter.printHeader("\n", schemaName + " has " + regularIndexes.size() + " regular and " +
                                 functionalIndexes.size() + " functional indexes.", "\n");  
        for (int i = 1; i <= regularIndexes.size(); i++) 
            outputWriter.printHeader("\n\t", " Regular Index# " + i + ": ", regularIndexes.get((i-1)));
        
        for (int i = 1; i <= functionalIndexes.size(); i++) 
            outputWriter.printHeader("\n\t", " Functional Index# " + i + ": ", functionalIndexes.get((i-1)));
    }

    private void retrieveExistingIndexes(int schemaId)
    {
        regularIndexes.clear();
        functionalIndexes.clear();
        StringBuilder sqlCommand = new StringBuilder("SELECT index_name, index_type from all_indexes where table_name = 'T" +
                schemaId + "'");
        try {
            SQLResult result = arServerUser.getListSQL(sqlCommand.toString(), 100, false);
            List<List<Value>> valueListList = result.getContents();
            for ( int i=0; i<valueListList.size(); ++i)
            {
               if (valueListList.get(i).get(1).toString().contains("FUNCTION-BASED"))
                   functionalIndexes.add(valueListList.get(i).get(0).toString());
               else
                   regularIndexes.add(valueListList.get(i).get(0).toString()); 
            }
        } 
        catch (ARException ex)
        {
            ;
        }
        return;
    }
    
    boolean isExistingIndex(String newName, String nlsSortParam)
    {
        if (nlsSortParam != null)
        {
            if ((functionalIndexes.contains(newName) == true) ||
               (functionalIndexes.contains(newName+"_CI") == true))
                return true;
        }
        else{
            if ((regularIndexes.contains(newName) == true) ||
               (regularIndexes.contains(newName+"_CS") == true))
            	return true;
        }
        return false;
    }
    
    private void createCurrentDBIndex(String schemaName, int schemaId, IndexInfo curIndex, String nlsSortParam) throws ARException {

        StringBuffer newIndexName = new StringBuffer(curIndex.getIndexName());
        
        /* Server does not add "_CI" for functional indexes */
        if (isExistingIndex(newIndexName.toString(), nlsSortParam) == true) 
        {
            outputWriter.printHeader("", " Index " + newIndexName + " already exists.", "\n");
            return;
        } 
        
        if (nlsSortParam != null)
            newIndexName = newIndexName.append("_CI");
        else 
            newIndexName = newIndexName.append("_CS");
        
        String sqlCommand = BuildCreateIndexCommand(schemaName, schemaId, curIndex, newIndexName.toString(), nlsSortParam);
        if (sqlCommand != null) {
            arServerUser.getListSQL(sqlCommand, 1, false);
            List<StatusInfo> status = arServerUser.getLastStatus();
            if (status.isEmpty() == false)
            {
                outputWriter.printHeader("", " Error while executing SQL Command: " + sqlCommand + status.get(0).getMessageNum(), "\n");
            }   
        }
        return;
    }
    
    private void dropCurrentDBIndex(String curIndex) {

        String sqlCommand = BuildDropIndexCommand(curIndex);
        try {
            arServerUser.getListSQL(sqlCommand, 1, false);
        } catch (ARException ex)
        {
            ;
        }
        return;
    }
    
    String BuildDropIndexCommand( String curIndex)   
    {
        StringBuilder sqlCommand = new StringBuilder("DROP INDEX " + curIndex);
        return sqlCommand.toString();
    }
     
    String BuildCreateIndexCommand( String schemaName, int schemaId, IndexInfo curIndex, String newIndexName, String nlsSortParam)  throws ARException 
    {
        boolean visitedCharacterField = false;
        List<Integer> fields = curIndex.getIndexFields();
        
        String tableName = "T" + schemaId;
        
        String sqlCommand = new String();
        
        if (curIndex.isUnique() == true)
            sqlCommand = "CREATE UNIQUE INDEX ";
        else
            sqlCommand = "CREATE INDEX " ;
         
       sqlCommand = sqlCommand.concat(newIndexName  + " ON " + tableName + " (" );
        
        
        if (fields.size() == 1)
        {
            /* get data type of field */
            FieldKey key = new FieldKey(schemaName, fields.get(0));

            FieldCriteria crit = new FieldCriteria();
            crit.setPropertiesToRetrieve(FieldCriteria.DATATYPE);
            Field field = arServerUser.getField(key.getFormName(), key.getFieldID(), crit);
            
            if (field.getDataType() == Constants.AR_DATA_TYPE_CHAR)
                visitedCharacterField = true;

            if ((nlsSortParam != null) && (field.getDataType() != Constants.AR_DATA_TYPE_CHAR))
                return null; /* can not create functional index on a non-character field */
            
            
            if ((nlsSortParam != null) && (visitedCharacterField == true))
                sqlCommand = sqlCommand.concat("nlssort(" + "C" + fields.get(0) + ", " + 
                        "'NLS_SORT=" + nlsSortParam + "'" + ")");
            else 
                sqlCommand = sqlCommand.concat("C" + fields.get(0));
        }
        else
        {
            /* for the multiple column case we build the column names in the */
            /* standard way by using the field id                            */          
            for (int i=0; i<fields.size(); ++i)
            {
                /* get data type of field */
                FieldKey key = new FieldKey(schemaName, fields.get(i));
                FieldCriteria crit = new FieldCriteria();
                crit.setPropertiesToRetrieve(FieldCriteria.DATATYPE);
                Field field = arServerUser.getField(key.getFormName(), key.getFieldID(), crit);
                if (field.getDataType() == Constants.AR_DATA_TYPE_CHAR)
                    visitedCharacterField = true;
                
                if (i > 0)
                    sqlCommand = sqlCommand.concat(", ");
                
                if ((nlsSortParam != null) && (field.getDataType() == Constants.AR_DATA_TYPE_CHAR))
                    sqlCommand = sqlCommand.concat("(nlssort(" + "C" + fields.get(i).toString() + ", " + 
                            "'NLS_SORT=" + nlsSortParam + "'" + "))");
                else 
                    sqlCommand = sqlCommand.concat("C" + fields.get(i).toString());
                    
            }
        }
        sqlCommand = sqlCommand.concat(")");
        if ((nlsSortParam != null) && (visitedCharacterField == false))
            /* did not find any character field, hence can not create functional index */
            return null;
        else
            return sqlCommand;
    }

    private void createDBIndexesForSchema(String schemaName, String nlsSortParam) throws ARException 
    {
        //Get all the user managed index associated with the schema
        FormCriteria criteria = new FormCriteria();
        criteria.setPropertiesToRetrieve(FormCriteria.INDEX_LIST);
        Form curForm = arServerUser.getForm(schemaName, criteria);
        if (curForm == null)
            return;
        int schemaId = getSchemaIdForSchema(schemaName);
        if (schemaId == 0)
        {
            outputWriter.printHeader("", "Error while retrieving schema id for schema " + schemaName + ".", "\n");
            return; /* can not continue */
        }
        retrieveExistingIndexes(schemaId);
        if (nlsSortParam != null) {
            /* create functional index for C1 */
            String indexName = "IT" + schemaId + "_CI";
            if (functionalIndexes.contains(indexName) == false) {
                StringBuffer sqlCommand = new StringBuffer("CREATE UNIQUE INDEX " + indexName + " ON T"+ schemaId + 
                                                            " (nlssort(C1, 'NLS_SORT=" + nlsSortParam +"'))");
                arServerUser.getListSQL(sqlCommand.toString(), 1, false);
                List<StatusInfo> status = arServerUser.getLastStatus();
                if (status.isEmpty() == false)
                {
                    outputWriter.printHeader("", " Error while executing SQL Command: " + sqlCommand + status.get(0).getMessageNum(), "\n");
                }             
            } else
                outputWriter.printHeader("", " Index " + indexName + " already exists.", "\n");
        }
        List<IndexInfo> indexList = curForm.getIndexInfo();
        
        if (indexList == null || indexList.size() == 0){
        	outputWriter.printHeader("There are 0 indexes on the form" , " ...skipping this form", "\n");
        	return;
        }
        
        for (int i = 0; i < indexList.size(); ++i) {
            IndexInfo curDBIndex = indexList.get(i);
            if (curDBIndex == null)
                continue;
            
            createCurrentDBIndex(schemaName, schemaId, curDBIndex, nlsSortParam);
        }
    }
    
    private void dropDBIndexesForSchema(String schemaName, boolean functionalIndex) throws ARException 
    {
        int schemaId = getSchemaIdForSchema(schemaName);
        if (schemaId == 0)
        {
            outputWriter.printHeader("", "Error while retrieving schema id for schema " + schemaName + ".", "\n");
            return; /* can not continue */
        }
        String C1IndexName = "IT" + schemaId;
        retrieveExistingIndexes(schemaId);
        if (functionalIndex == true)
        {
        	if (functionalIndexes.size() == 0){
        		outputWriter.printHeader("There are 0 functional indexes on the form", " ... skipping this form", "\n");
        		return;
        	}
        	
            for (int i=0; i< functionalIndexes.size(); ++i){
                dropCurrentDBIndex(functionalIndexes.get(i));
            }
        } else {
        	if (regularIndexes.size() == 0){
        		outputWriter.printHeader("There are 0 indexes on the form", " ... skipping this form", "\n");
        		return;
        	}        	
            for (int i=0; i< regularIndexes.size(); ++i) {
                if (regularIndexes.get(i).equals(C1IndexName) == false) /*  don't drop regular index on C1 */
                    dropCurrentDBIndex(regularIndexes.get(i));
            }
        }
        
        /* If regular indexes were dropped, rename functional indexes and get rid of suffix "_CI" */
        if (functionalIndex == false)
        {
        	String C1 = new String (C1IndexName + "_CI");
            for (int i=0; i < functionalIndexes.size(); ++i) {
                String curIndexName = functionalIndexes.get(i);
                if (curIndexName.equals(C1) == true)
                    continue; /* do not rename the index on C1, preserve dual index */
                if ((curIndexName.endsWith("_CI") == true) && (functionalIndexes.get(i).equals(C1) == false))
                {
                    String newName = curIndexName.replace("_CI", "");
                    StringBuffer sqlCommand = new StringBuffer("ALTER INDEX " + curIndexName + " RENAME TO " + newName);
                    try {
                    	arServerUser.getListSQL(sqlCommand.toString(), 1, false);
                    }catch (ARException e){
                    	// ignore
                    }
                }
            }
        } else         /* If functional indexes were dropped, rename functional indexes and get rid of suffix "_CS" */           
            {
        		String C1 = new String (C1IndexName + "_CS");
                for (int i = 0; i < regularIndexes.size(); ++i) {
                    String curIndexName = regularIndexes.get(i);
                    if (curIndexName.equals(C1) == true)
                        continue; /* do not rename the index on C1, preserve dual index */
                    if ((curIndexName.endsWith("_CS") == true) && (regularIndexes.get(i).equals(C1) == false))
                    {
                        String newName = curIndexName.replace("_CS", "");
                        StringBuffer sqlCommand = new StringBuffer("ALTER INDEX " + curIndexName + " RENAME TO " + newName);
                        try {
                        	arServerUser.getListSQL(sqlCommand.toString(), 1, false);
                        } catch (ARException e){
                        	// ignore 
                        }
                    }
                }
            }
    }
    
    
        
    /**
     * @param args
     */
    public static void main(String[] args) {
        OracleFunctionalIndexHelper indexHelper = new OracleFunctionalIndexHelper();
        String nlsSortParam = null;
        try {  
            JavaDriver.getThreadControlBlockPtr().setPrimaryThread(true);
            JavaDriver.getThreadControlBlockPtr().setCurrentInputToStdIn();
            JavaDriver.getThreadControlBlockPtr().setOutputToStdOut();
            outputWriter.printHeader("\t\t\t", "Oracle Functional Index Helper Utility", "\n");
            outputWriter.printHeader("\n", "===================================================================================================", "");
            outputWriter.printHeader("\n", "This is an un-supported convenience program which is being provide on ASIS basis to help customers", "");
            outputWriter.printHeader("\n", "in converting regular indexes to functional indexes and vice-versa. This utility is supposed to be ", "");
            outputWriter.printHeader("\n", "used in context of Oracle case insensitive search configuration in AR Server. The utility accepts an", "");
            outputWriter.printHeader("\n", "optional input argument which controls the forms which will be considered for index conversion. If the", "");
            outputWriter.printHeader("\n", "command line argument \"Input File containing the form names\" is not specified, the utility will be", "");
            outputWriter.printHeader("\n", "run on all the forms available on the server. The utility supports ADD, DROP and VIEW operations for", "");
            outputWriter.printHeader("\n", "indexes on the server. For ADD and DROP operations, index type (functional or regular) must be specified.", "");
            outputWriter.printHeader("\n", "The utility supports NLS_SORT parameters [BINARY_CI(0),BINARY_AI(1), GENERIC_M(2)] for case insensitive", "");
            outputWriter.printHeader("\n", "searches. The default value is BINARY_CI.", "\n");
            outputWriter.printHeader("\n", "The utility accepts following input values:", "");
            outputWriter.printHeader("\n\t", "Server Host: < name of the server, default is localhost >", "");
            outputWriter.printHeader("\n\t", "Server Port: < server port, default is 0 >", "");
            outputWriter.printHeader("\n\t", "User Name: < valid AR Server admin user >", "");
            outputWriter.printHeader("\n\t", "Password:  < AR Server admin password >", "");
            outputWriter.printHeader("\n\t", "Input File containing the form names: < Provide this argument to run on specific forms only>", "");
            outputWriter.printHeader("\n\t", "Index Operation Type: <Index operation type[Add(0),Drop(1),View(2), Exit(3)]>  ", "");
            outputWriter.printHeader("\n", "===================================================================================================", "\n\n");
            
            String serverName = InputReader.getString("Server Host:", "localhost");
            int serverPort = InputReader.getInt("Server Port:", 0);
            String userName = InputReader.getString("User Name:", "Demo");
            String password = InputReader.getString("Password:", "");
            String locale = null;
            indexHelper.arServerUser = new ARServerUser(userName, password, locale, serverName, serverPort);
            try {
            	indexHelper.arServerUser.login();
            	if (!indexHelper.arServerUser.isAdministrator()){
            		outputWriter.printHeader("*** ERROR ***", " Need AR Administrator privilege to run the utility",  "\nIndex Helper utility stopped");
                	return;
            	}
            	/* do not want to see TIMEOUT errors in this utility */
            	/* set the timeout to a very large value ( 8 hours ) */
            	indexHelper.arServerUser.setTimeoutNormal(ARConstantsBase.AR_DEFAULT_CACHEEVENT_TIMEOUT);
            	indexHelper.arServerUser.setTimeoutLong(ARConstantsBase.AR_DEFAULT_CACHEEVENT_TIMEOUT);
            	indexHelper.arServerUser.setTimeoutXLong(ARConstantsBase.AR_DEFAULT_CACHEEVENT_TIMEOUT);
            } catch(ARException e){
            	String msg = e.getMessage();
            	outputWriter.printHeader("*** ERROR ***: Login failed for user: ", userName, "\n");
            	if (msg != null)
            		outputWriter.printHeader(msg, "\n", "Index Helper utility stopped");
            	return;
            }
            
            InputReader.setNullPromptOption(true);
            String fileName = InputReader.getString("Input File containing the form names:", "");

            /* Get AR Server database type*/
            int[] requestList = new int[1];
            requestList[0] = 1;
            ServerInfoMap serverInfoMap = indexHelper.arServerUser.getServerInfo(requestList);
            String dbType = serverInfoMap.get(1).toString();
            
            /* if not oracle then quit */
            if (dbType.equals("SQL -- Oracle") == false){
            	outputWriter.printHeader("*** ERROR ***: Utility supports only Oracle Databse, underline DB detected: ", dbType, "\nIndex Helper utility stopped");
            	return;
            }
            
                int opType = COMMAND_OPTION_VIEW_INDEX;
                int indexType = 0;
                try{
                indexHelper.readSchemaNames(fileName);
                } catch (FileNotFoundException e){
                	String msg = e.getMessage();
                	outputWriter.printHeader("*** ERROR ***: Invalid File: ", fileName != null? fileName  :"", "\n");
                	if (msg != null)
                		outputWriter.printHeader(msg, "\n", "Index Helper utility stopped");
                	return;                	
                }
                /* counter for valid command option attempt - max 3 */
                int invalidComandCount = 0;
                outputWriter.printHeader("", "Processing " + indexHelper.getSchemaCount() + " Forms.", "\n");
                while (opType != COMMAND_OPTION_QUIT_APP)
                {
                    nlsSortParam = null;
                    opType = InputReader.getInt("Index Operation Type: [Add(0),Drop(1),View(2), Exit(3)]", 2);
                    if (opType < COMMAND_OPTION_ADD_INDEX || opType > COMMAND_OPTION_MAX_USED){
                    	if (invalidComandCount > 3){
                    		outputWriter.printHeader("*** ERROR ***: Invalid command option: ", "Max attempt", "\nIndex Helper utility stopped");
                    		return;
                    	}
                    	outputWriter.printHeader("*** ERROR ***: Invalid command option: ", "", "\n");
                    	invalidComandCount++;
                    	continue;
                    }
                    /* reset counter for any valid command option */
                    invalidComandCount = 0;
                    if (opType == COMMAND_OPTION_ADD_INDEX)
                        indexType = InputReader.getInt("Index type to add: [REGULAR(0),FUNCTIONAL(1)]", 1);
                    if (opType == COMMAND_OPTION_DROP_INDEX)
                    {
                        indexType = InputReader.getInt("Index type to drop: [REGULAR(0),FUNCTIONAL(1)]", 1);
                        if (indexType == COMMAND_OPTION_REGULAR_INDEX)
                            nlsSortParam = null; 
                    }

                    if ((opType == COMMAND_OPTION_ADD_INDEX) && (indexType == COMMAND_OPTION_FUNCTIONAL_INDEX))
                    {
                        int nlsSortType = InputReader.getInt("NLS_SORT parameter: [BINARY_CI(0),BINARY_AI(1), GENERIC_M(2)", 0);
                        switch (nlsSortType)
                        {
                        case 0:
                            nlsSortParam = "BINARY_CI";
                            break;
                        case 1:
                            nlsSortParam = "BINARY_AI";
                            break;
                        case 2:
                            nlsSortParam = "GENERIC_M";
                            break;
                        default:
                            nlsSortParam = "BINARY_CI";
                            break;     
                        }
                    }
                    Calendar now = Calendar.getInstance();
                    long startTime = now.getTimeInMillis();
                    switch (opType)
                    {
                    case COMMAND_OPTION_ADD_INDEX:
                        indexHelper.createDBIndexes(nlsSortParam); 
                        break;
                    case COMMAND_OPTION_DROP_INDEX:
                        if (indexType == COMMAND_OPTION_FUNCTIONAL_INDEX)
                            indexHelper.dropDBIndexes(true);
                        else
                            indexHelper.dropDBIndexes(false);
                        
                        break;
                    case COMMAND_OPTION_VIEW_INDEX:
                        indexHelper.viewDBIndexes();
                        break;
                    default:
                        break;   
                    }
                    now = Calendar.getInstance();
                    long endTime = now.getTimeInMillis();
                    long elapsedTime = (endTime - startTime)/1000;
                    outputWriter.printHeader("", "\n" , "\n");
                    outputWriter.printHeader("", "Current Run Report         \n" , "\n");
                    outputWriter.printHeader("", "==========================================", "\n");
                    outputWriter.printHeader("", "Processing Completed in " + elapsedTime + " seconds.", "\n");
                    outputWriter.printHeader("", "==========================================", "\n");
                }
        } catch (Exception e) {
            outputWriter.printString("Error in executing the command: ", e.getMessage(), "\nIndex Helper utility stopped");            
        } finally {
            try {
                indexHelper.arServerUser.logout();
             
             } catch (Exception e) {
                 e.printStackTrace();
             } finally {
                 System.exit(0); 
             }
        }
    }
}
