/*
 * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.
 */

package org.wso2.micro.integrator.coordination.query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * This class provide list of SQL queries for different databases.
 */
public class QueryManager {
    private final Map<DBQueries, String> mysqlQueryMap =
            Collections.unmodifiableMap(new HashMap<DBQueries, String>() {{
                put(DBQueries.IS_LEADER_STATUS_TABLE_EXISTS, "SELECT * FROM LEADER_STATUS_TABLE");
                put(DBQueries.IS_CLUSTER_NODE_STATUS_TABLE_EXISTS, "SELECT * FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.IS_MEMBERSHIP_EVENT_TABLE_EXISTS, "SELECT * FROM MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.IS_REMOVED_MEMBERS_TABLE_EXISTS, "SELECT * FROM REMOVED_MEMBERS_TABLE");

                put(DBQueries.INSERT_COORDINATOR_ROW, "INSERT INTO LEADER_STATUS_TABLE (GROUP_ID, NODE_ID, LAST_HEARTBEAT) VALUES (?,?,?)");
                put(DBQueries.INSERT_NODE_HEARTBEAT_ROW, "INSERT INTO CLUSTER_NODE_STATUS_TABLE (NODE_ID, LAST_HEARTBEAT, GROUP_ID, IS_NEW_NODE) VALUES (?,?,?,1)");
                put(DBQueries.INSERT_MEMBERSHIP_EVENT, "INSERT INTO MEMBERSHIP_EVENT_TABLE (NODE_ID, GROUP_ID, CHANGE_TYPE, CHANGED_MEMBER_ID) VALUES ( ?,?,?,?)");
                put(DBQueries.INSERT_REMOVED_MEMBER_DETAILS, "INSERT INTO REMOVED_MEMBERS_TABLE (NODE_ID, GROUP_ID, REMOVED_MEMBER_ID) VALUES ( ?,?,?)");

                put(DBQueries.UPDATE_COORDINATOR_HEARTBEAT, "UPDATE LEADER_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.UPDATE_NODE_HEARTBEAT, "UPDATE CLUSTER_NODE_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");

                put(DBQueries.MARK_NODE_NOT_NEW, "UPDATE CLUSTER_NODE_STATUS_TABLE SET IS_NEW_NODE =0 WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.SELECT_MEMBERSHIP_EVENT, "SELECT CHANGE_TYPE, CHANGED_MEMBER_ID, GROUP_ID FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =? ORDER BY CHANGE_TYPE");
                put(DBQueries.SELECT_REMOVED_MEMBER_DETAILS, "SELECT REMOVED_MEMBER_ID, GROUP_ID FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND GROUP_ID =?");

                put(DBQueries.GET_COORDINATOR_NODE_ID, "SELECT NODE_ID FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_ROW_FOR_NODE_ID, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_HEARTBEAT, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_ALL_NODE_HEARTBEAT, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=?");
                put(DBQueries.GET_NODE_DATA, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=? AND NODE_ID=?");

                put(DBQueries.DELETE_COORDINATOR, "DELETE FROM LEADER_STATUS_TABLE WHERE GROUP_ID =? AND LAST_HEARTBEAT < ?");
                put(DBQueries.DELETE_NODE_HEARTBEAT, "DELETE FROM CLUSTER_NODE_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.DELETE_REMOVED_MEMBER_DETAIL_FOR_NODE, "DELETE FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND  GROUP_ID =?");

                put(DBQueries.CLEAR_NODE_HEARTBEATS, "DELETE FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.CLEAR_COORDINATOR_HEARTBEAT, "DELETE FROM LEADER_STATUS_TABLE");
                put(DBQueries.CLEAR_ALL_MEMBERSHIP_EVENTS, "DELETE FROM  MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.CLEAN_MEMBERSHIP_EVENTS_FOR_NODE, "DELETE FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =?");
            }});

    private final Map<DBQueries, String> postgreSQLQueryMap =
            Collections.unmodifiableMap(new HashMap<DBQueries, String>() {{
                put(DBQueries.IS_LEADER_STATUS_TABLE_EXISTS, "SELECT 1 FROM LEADER_STATUS_TABLE");
                put(DBQueries.IS_CLUSTER_NODE_STATUS_TABLE_EXISTS, "SELECT 1 FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.IS_MEMBERSHIP_EVENT_TABLE_EXISTS, "SELECT 1 FROM MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.IS_REMOVED_MEMBERS_TABLE_EXISTS, "SELECT 1 FROM REMOVED_MEMBERS_TABLE");

                put(DBQueries.INSERT_COORDINATOR_ROW, "INSERT INTO LEADER_STATUS_TABLE (GROUP_ID, NODE_ID, LAST_HEARTBEAT) VALUES (?,?,?)");
                put(DBQueries.INSERT_NODE_HEARTBEAT_ROW, "INSERT INTO CLUSTER_NODE_STATUS_TABLE (NODE_ID, LAST_HEARTBEAT, GROUP_ID, IS_NEW_NODE) VALUES (?,?,?,1)");
                put(DBQueries.INSERT_MEMBERSHIP_EVENT, "INSERT INTO MEMBERSHIP_EVENT_TABLE (NODE_ID, GROUP_ID, CHANGE_TYPE, CHANGED_MEMBER_ID) VALUES ( ?,?,?,?)");
                put(DBQueries.INSERT_REMOVED_MEMBER_DETAILS, "INSERT INTO REMOVED_MEMBERS_TABLE (NODE_ID, GROUP_ID, REMOVED_MEMBER_ID) VALUES ( ?,?,?)");

                put(DBQueries.UPDATE_COORDINATOR_HEARTBEAT, "UPDATE LEADER_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.UPDATE_NODE_HEARTBEAT, "UPDATE CLUSTER_NODE_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");

                put(DBQueries.MARK_NODE_NOT_NEW, "UPDATE CLUSTER_NODE_STATUS_TABLE SET IS_NEW_NODE =0 WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.SELECT_MEMBERSHIP_EVENT, "SELECT CHANGE_TYPE, CHANGED_MEMBER_ID, GROUP_ID FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =? ORDER BY CHANGE_TYPE");
                put(DBQueries.SELECT_REMOVED_MEMBER_DETAILS, "SELECT REMOVED_MEMBER_ID, GROUP_ID FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND GROUP_ID =?");

                put(DBQueries.GET_COORDINATOR_NODE_ID, "SELECT NODE_ID FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_ROW_FOR_NODE_ID, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_HEARTBEAT, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_ALL_NODE_HEARTBEAT, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=?");
                put(DBQueries.GET_NODE_DATA, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=? AND NODE_ID=?");

                put(DBQueries.DELETE_COORDINATOR, "DELETE FROM LEADER_STATUS_TABLE WHERE GROUP_ID =? AND LAST_HEARTBEAT < ?");
                put(DBQueries.DELETE_NODE_HEARTBEAT, "DELETE FROM CLUSTER_NODE_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.DELETE_REMOVED_MEMBER_DETAIL_FOR_NODE, "DELETE FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND  GROUP_ID =?");
                put(DBQueries.CLEAR_NODE_HEARTBEATS, "DELETE FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.CLEAR_COORDINATOR_HEARTBEAT, "DELETE FROM LEADER_STATUS_TABLE");
                put(DBQueries.CLEAR_ALL_MEMBERSHIP_EVENTS, "DELETE FROM  MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.CLEAN_MEMBERSHIP_EVENTS_FOR_NODE, "DELETE FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =?");
            }});

    private final Map<DBQueries, String> microsoftSQLServerQueryMap =
            Collections.unmodifiableMap(new HashMap<DBQueries, String>() {{
                put(DBQueries.IS_LEADER_STATUS_TABLE_EXISTS, "SELECT TOP 1 1 FROM LEADER_STATUS_TABLE");
                put(DBQueries.IS_CLUSTER_NODE_STATUS_TABLE_EXISTS, "SELECT TOP 1 1 FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.IS_MEMBERSHIP_EVENT_TABLE_EXISTS, "SELECT TOP 1 1 FROM MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.IS_REMOVED_MEMBERS_TABLE_EXISTS, "SELECT TOP 1 1 FROM REMOVED_MEMBERS_TABLE");

                put(DBQueries.INSERT_COORDINATOR_ROW, "INSERT INTO LEADER_STATUS_TABLE (GROUP_ID, NODE_ID, LAST_HEARTBEAT) VALUES (?,?,?)");
                put(DBQueries.INSERT_NODE_HEARTBEAT_ROW, "INSERT INTO CLUSTER_NODE_STATUS_TABLE (NODE_ID, LAST_HEARTBEAT, GROUP_ID, IS_NEW_NODE) VALUES (?,?,?,1)");
                put(DBQueries.INSERT_MEMBERSHIP_EVENT, "INSERT INTO MEMBERSHIP_EVENT_TABLE (NODE_ID, GROUP_ID, CHANGE_TYPE, CHANGED_MEMBER_ID) VALUES ( ?,?,?,?)");
                put(DBQueries.INSERT_REMOVED_MEMBER_DETAILS, "INSERT INTO REMOVED_MEMBERS_TABLE (NODE_ID, GROUP_ID, REMOVED_MEMBER_ID) VALUES ( ?,?,?)");

                put(DBQueries.UPDATE_COORDINATOR_HEARTBEAT, "UPDATE LEADER_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.UPDATE_NODE_HEARTBEAT, "UPDATE CLUSTER_NODE_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");

                put(DBQueries.MARK_NODE_NOT_NEW, "UPDATE CLUSTER_NODE_STATUS_TABLE SET IS_NEW_NODE =0 WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.SELECT_MEMBERSHIP_EVENT, "SELECT CHANGE_TYPE, CHANGED_MEMBER_ID, GROUP_ID FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =? ORDER BY CHANGE_TYPE");
                put(DBQueries.SELECT_REMOVED_MEMBER_DETAILS, "SELECT REMOVED_MEMBER_ID, GROUP_ID FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND GROUP_ID =?");

                put(DBQueries.GET_COORDINATOR_NODE_ID, "SELECT NODE_ID FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_ROW_FOR_NODE_ID, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_HEARTBEAT, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_ALL_NODE_HEARTBEAT, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=?");
                put(DBQueries.GET_NODE_DATA, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=? AND NODE_ID=?");

                put(DBQueries.DELETE_COORDINATOR, "DELETE FROM LEADER_STATUS_TABLE WHERE GROUP_ID =? AND LAST_HEARTBEAT < ?");
                put(DBQueries.DELETE_NODE_HEARTBEAT, "DELETE FROM CLUSTER_NODE_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.DELETE_REMOVED_MEMBER_DETAIL_FOR_NODE, "DELETE FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND  GROUP_ID =?");
                put(DBQueries.CLEAR_NODE_HEARTBEATS, "DELETE FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.CLEAR_COORDINATOR_HEARTBEAT, "DELETE FROM LEADER_STATUS_TABLE");
                put(DBQueries.CLEAR_ALL_MEMBERSHIP_EVENTS, "DELETE FROM  MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.CLEAN_MEMBERSHIP_EVENTS_FOR_NODE, "DELETE FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =?");
            }});

    private final Map<DBQueries, String> oracleQueryMap =
            Collections.unmodifiableMap(new HashMap<DBQueries, String>() {{
                put(DBQueries.IS_LEADER_STATUS_TABLE_EXISTS, "SELECT 1 FROM LEADER_STATUS_TABLE WHERE rownum=1");
                put(DBQueries.IS_CLUSTER_NODE_STATUS_TABLE_EXISTS, "SELECT 1 FROM CLUSTER_NODE_STATUS_TABLE WHERE rownum=1");
                put(DBQueries.IS_MEMBERSHIP_EVENT_TABLE_EXISTS, "SELECT 1 FROM MEMBERSHIP_EVENT_TABLE WHERE rownum=1");
                put(DBQueries.IS_REMOVED_MEMBERS_TABLE_EXISTS, "SELECT 1 FROM REMOVED_MEMBERS_TABLE WHERE rownum=1");

                put(DBQueries.INSERT_COORDINATOR_ROW, "INSERT INTO LEADER_STATUS_TABLE (GROUP_ID, NODE_ID, LAST_HEARTBEAT) VALUES (?,?,?)");
                put(DBQueries.INSERT_NODE_HEARTBEAT_ROW, "INSERT INTO CLUSTER_NODE_STATUS_TABLE (NODE_ID, LAST_HEARTBEAT, GROUP_ID, IS_NEW_NODE) VALUES (?,?,?,1)");
                put(DBQueries.INSERT_MEMBERSHIP_EVENT, "INSERT INTO MEMBERSHIP_EVENT_TABLE (NODE_ID, GROUP_ID, CHANGE_TYPE, CHANGED_MEMBER_ID) VALUES ( ?,?,?,?)");
                put(DBQueries.INSERT_REMOVED_MEMBER_DETAILS, "INSERT INTO REMOVED_MEMBERS_TABLE (NODE_ID, GROUP_ID, REMOVED_MEMBER_ID) VALUES ( ?,?,?)");

                put(DBQueries.UPDATE_COORDINATOR_HEARTBEAT, "UPDATE LEADER_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.UPDATE_NODE_HEARTBEAT, "UPDATE CLUSTER_NODE_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");

                put(DBQueries.MARK_NODE_NOT_NEW, "UPDATE CLUSTER_NODE_STATUS_TABLE SET IS_NEW_NODE =0 WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.SELECT_MEMBERSHIP_EVENT, "SELECT CHANGE_TYPE, CHANGED_MEMBER_ID, GROUP_ID FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =? ORDER BY CHANGE_TYPE");
                put(DBQueries.SELECT_REMOVED_MEMBER_DETAILS, "SELECT REMOVED_MEMBER_ID, GROUP_ID FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND GROUP_ID =?");

                put(DBQueries.GET_COORDINATOR_NODE_ID, "SELECT NODE_ID FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_ROW_FOR_NODE_ID, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_HEARTBEAT, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_ALL_NODE_HEARTBEAT, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=?");
                put(DBQueries.GET_NODE_DATA, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=? AND NODE_ID=?");

                put(DBQueries.DELETE_COORDINATOR, "DELETE FROM LEADER_STATUS_TABLE WHERE GROUP_ID =? AND LAST_HEARTBEAT < ?");
                put(DBQueries.DELETE_NODE_HEARTBEAT, "DELETE FROM CLUSTER_NODE_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.DELETE_REMOVED_MEMBER_DETAIL_FOR_NODE, "DELETE FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND  GROUP_ID =?");
                put(DBQueries.CLEAR_NODE_HEARTBEATS, "DELETE FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.CLEAR_COORDINATOR_HEARTBEAT, "DELETE FROM LEADER_STATUS_TABLE");
                put(DBQueries.CLEAR_ALL_MEMBERSHIP_EVENTS, "DELETE FROM  MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.CLEAN_MEMBERSHIP_EVENTS_FOR_NODE, "DELETE FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =?");
            }});

    private final Map<DBQueries, String> db2QueryMap =
            Collections.unmodifiableMap(new HashMap<DBQueries, String>() {{
                put(DBQueries.IS_LEADER_STATUS_TABLE_EXISTS, "SELECT * FROM LEADER_STATUS_TABLE");
                put(DBQueries.IS_CLUSTER_NODE_STATUS_TABLE_EXISTS, "SELECT * FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.IS_MEMBERSHIP_EVENT_TABLE_EXISTS, "SELECT * FROM MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.IS_REMOVED_MEMBERS_TABLE_EXISTS, "SELECT * FROM REMOVED_MEMBERS_TABLE");

                put(DBQueries.INSERT_COORDINATOR_ROW, "INSERT INTO LEADER_STATUS_TABLE (GROUP_ID, NODE_ID, LAST_HEARTBEAT) VALUES (?,?,?)");
                put(DBQueries.INSERT_NODE_HEARTBEAT_ROW, "INSERT INTO CLUSTER_NODE_STATUS_TABLE (NODE_ID, LAST_HEARTBEAT, GROUP_ID, IS_NEW_NODE) VALUES (?,?,?,1)");
                put(DBQueries.INSERT_MEMBERSHIP_EVENT, "INSERT INTO MEMBERSHIP_EVENT_TABLE (NODE_ID, GROUP_ID, CHANGE_TYPE, CHANGED_MEMBER_ID) VALUES ( ?,?,?,?)");
                put(DBQueries.INSERT_REMOVED_MEMBER_DETAILS, "INSERT INTO REMOVED_MEMBERS_TABLE (NODE_ID, GROUP_ID, REMOVED_MEMBER_ID) VALUES ( ?,?,?)");

                put(DBQueries.UPDATE_COORDINATOR_HEARTBEAT, "UPDATE LEADER_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.UPDATE_NODE_HEARTBEAT, "UPDATE CLUSTER_NODE_STATUS_TABLE SET LAST_HEARTBEAT =? WHERE NODE_ID =? AND GROUP_ID =?");

                put(DBQueries.MARK_NODE_NOT_NEW, "UPDATE CLUSTER_NODE_STATUS_TABLE SET IS_NEW_NODE =0 WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.SELECT_MEMBERSHIP_EVENT, "SELECT CHANGE_TYPE, CHANGED_MEMBER_ID, GROUP_ID FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =? ORDER BY CHANGE_TYPE");
                put(DBQueries.SELECT_REMOVED_MEMBER_DETAILS, "SELECT REMOVED_MEMBER_ID, GROUP_ID FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND GROUP_ID =?");

                put(DBQueries.GET_COORDINATOR_NODE_ID, "SELECT NODE_ID FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_ROW_FOR_NODE_ID, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.GET_COORDINATOR_HEARTBEAT, "SELECT LAST_HEARTBEAT FROM LEADER_STATUS_TABLE WHERE GROUP_ID =?");
                put(DBQueries.GET_ALL_NODE_HEARTBEAT, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=?");
                put(DBQueries.GET_NODE_DATA, "SELECT GROUP_ID, NODE_ID, LAST_HEARTBEAT, IS_NEW_NODE FROM CLUSTER_NODE_STATUS_TABLE WHERE GROUP_ID=? AND NODE_ID=?");

                put(DBQueries.DELETE_COORDINATOR, "DELETE FROM LEADER_STATUS_TABLE WHERE GROUP_ID =? AND LAST_HEARTBEAT < ?");
                put(DBQueries.DELETE_NODE_HEARTBEAT, "DELETE FROM CLUSTER_NODE_STATUS_TABLE WHERE NODE_ID =? AND GROUP_ID =?");
                put(DBQueries.DELETE_REMOVED_MEMBER_DETAIL_FOR_NODE, "DELETE FROM REMOVED_MEMBERS_TABLE WHERE NODE_ID =? AND REMOVED_MEMBER_ID =? AND  GROUP_ID =?");
                put(DBQueries.CLEAR_NODE_HEARTBEATS, "DELETE FROM CLUSTER_NODE_STATUS_TABLE");
                put(DBQueries.CLEAR_COORDINATOR_HEARTBEAT, "DELETE FROM LEADER_STATUS_TABLE");
                put(DBQueries.CLEAR_ALL_MEMBERSHIP_EVENTS, "DELETE FROM  MEMBERSHIP_EVENT_TABLE");
                put(DBQueries.CLEAN_MEMBERSHIP_EVENTS_FOR_NODE, "DELETE FROM MEMBERSHIP_EVENT_TABLE WHERE NODE_ID =?");
            }});

    public enum DBQueries {
        IS_LEADER_STATUS_TABLE_EXISTS,
        IS_CLUSTER_NODE_STATUS_TABLE_EXISTS,
        IS_MEMBERSHIP_EVENT_TABLE_EXISTS,
        IS_REMOVED_MEMBERS_TABLE_EXISTS,
        INSERT_COORDINATOR_ROW,
        INSERT_NODE_HEARTBEAT_ROW,
        INSERT_MEMBERSHIP_EVENT,
        INSERT_REMOVED_MEMBER_DETAILS,
        UPDATE_COORDINATOR_HEARTBEAT,
        UPDATE_NODE_HEARTBEAT,
        MARK_NODE_NOT_NEW,
        SELECT_MEMBERSHIP_EVENT,
        SELECT_REMOVED_MEMBER_DETAILS,
        GET_COORDINATOR_NODE_ID,
        GET_COORDINATOR_ROW_FOR_NODE_ID,
        GET_COORDINATOR_HEARTBEAT,
        GET_ALL_NODE_HEARTBEAT,
        GET_NODE_DATA,
        DELETE_COORDINATOR,
        DELETE_NODE_HEARTBEAT,
        DELETE_REMOVED_MEMBER_DETAIL_FOR_NODE,
        CLEAR_NODE_HEARTBEATS,
        CLEAR_COORDINATOR_HEARTBEAT,
        CLEAR_ALL_MEMBERSHIP_EVENTS,
        CLEAN_MEMBERSHIP_EVENTS_FOR_NODE,
    }

    public enum DBTypes {
        MYSQL,
        POSTGRESQL,
        MICROSOFTSQLSERVER,
        ORACLE,
        DB2
    }

    private DBTypes dbTypes;

    private final Log log = LogFactory.getLog(QueryManager.class);

    public QueryManager(String databaseType) {
        if ("MySQL".equals(databaseType)) {
            this.dbTypes = DBTypes.MYSQL;
        } else if ("PostgreSQL".equals(databaseType)) {
            this.dbTypes = DBTypes.POSTGRESQL;
        } else if ("Oracle".equals(databaseType)) {
            this.dbTypes = DBTypes.ORACLE;
        } else if (databaseType.toLowerCase(Locale.ENGLISH).contains("DB2".toLowerCase(Locale.ENGLISH))) {
            this.dbTypes = DBTypes.DB2;
        } else {
            this.dbTypes = DBTypes.MICROSOFTSQLSERVER;
        }
    }
    public String getQuery(DBQueries dbQueries) {
        switch (this.dbTypes) {
            case MYSQL: return mysqlQueryMap.get(dbQueries);
            case POSTGRESQL: return postgreSQLQueryMap.get(dbQueries);
            case ORACLE: return oracleQueryMap.get(dbQueries);
            case DB2: return db2QueryMap.get(dbQueries);
            default: return microsoftSQLServerQueryMap.get(dbQueries);
        }
    }
}
