package io.mycat.proxy.monitor;

import io.mycat.MycatException;
import io.mycat.proxy.handler.backend.MySQLSynContext;
import io.mycat.proxy.packet.MySQLPayloadType;
import io.mycat.proxy.reactor.SessionThread;
import io.mycat.proxy.session.MySQLClientSession;
import io.mycat.proxy.session.MycatSession;
import io.mycat.proxy.session.Session;

import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;

/**
 * @author jamie12221 date 2019-05-20 11:32
 **/

public interface MycatMonitorCallback {

    final MycatMonitorCallback EMPTY = new AbstractMonitorCallback() {

    };

    static SessionThread getThread() {
        Thread thread = Thread.currentThread();
        return (SessionThread) thread;
    }

    static Session getSession() {
        SessionThread thread = getThread();
        Session curSession = thread.getCurSession();
        if (curSession instanceof MycatSession) {
            return curSession;
        } else if (curSession instanceof MySQLClientSession) {
            MycatSession mycatSession = ((MySQLClientSession) curSession).getMycat();
            if (mycatSession == null) {
                return curSession;
            } else {
                return mycatSession;
            }
        } else {
            throw new MycatException("unknown session");
        }
    }

    void onOrginSQL(Session session, String sql);

    void onFrontRead(Session session, ByteBuffer view, int startIndex, int len);

    void onPayloadType(Session session, MySQLPayloadType type
                       //,ByteBuffer view, int startIndex, int len
    );

    void onBackendWrite(Session session, ByteBuffer view, int startIndex,
                        int len);

    void onBackendRead(Session session, ByteBuffer view, int startIndex,
                       int len);

    void onFrontWrite(Session session, ByteBuffer view, int startIndex, int len);

    void onMySQLSessionServerStatusChanged(Session session, int serverStatus);

    void onAllocateByteBuffer(ByteBuffer buffer, Session session);

    void onSyncSQL(MySQLSynContext mycatSession, String sql, MySQLClientSession session);

    void onSynchronizationState(MySQLClientSession session);

    void onRecycleByteBuffer(ByteBuffer buffer, Session session);

    void onExpandByteBuffer(ByteBuffer buffer, Session session);

    void onNewMycatSession(MycatSession session);

    void onBindMySQLSession(MycatSession mycat, MySQLClientSession session);

    void onUnBindMySQLSession(MycatSession mycat, MySQLClientSession session);


    void onNewMySQLSession(MySQLClientSession session);

    void onAddIdleMysqlSession(MySQLClientSession session);

    void onGetIdleMysqlSession(MySQLClientSession session);

    void onRouteSQL(Session session, String replicaName, String defaultDataBase, String sql);

    void onRouteSQLResult(Session session, String replicaName, String defaultDataBase, String dataSource,
                          byte[] payload);

    void onRouteSQLResult(Session session, String replicaName, String defaultDataBase, String dataSource,
                          String sql);

    /**
     * exception
     */
    void onBackendConCreateWriteException(Session session, Exception e);

    void onBackendConCreateConnectException(Session session, Exception e);

    void onBackendConCreateReadException(Session session, Exception e);

    void onBackendConCreateClear(Session session);

    void onBackendResultSetReadException(Session session, Exception e);

    void onBackendResultSetWriteException(Session session, Exception e);

    void onBackendResultSetWriteClear(Session session);

    void onResultSetWriteException(Session session, Exception e);

    void onResultSetReadException(Session session, Exception e);

    void onResultSetClear(Session session);

    void onIdleReadException(Session session, Exception e);

    void onAuthHandlerWriteException(Session session, Exception e);

    void onAuthHandlerReadException(Session session, Exception e);

    void onAuthHandlerClear(Session session);

    void onPacketExchangerWriteException(Session session, Exception e);

    void onPacketExchangerException(Session session, Exception e);

    void onPacketExchangerClear(Session session);

    void onMycatHandlerWriteException(Session session, Exception e);

//  void onMycatHandlerExchangerException(Session session, Exception e);

    void onMycatHandlerClear(Session session);

    void onCloseMysqlSession(MySQLClientSession session, boolean normal, String reson);


    void onRequestException(MySQLClientSession session, Exception e);

    void onRequestClear(MySQLClientSession session);

    void onBackendConCreateException(Session session, Exception e);

    void onResultSetException(MySQLClientSession session, Exception e);

    void onMycatHandlerReadException(MycatSession mycat, Exception e);

    void onMycatHandlerException(MycatSession mycat, Exception e);

    void onMycatHandlerCloseException(MycatSession mycat, ClosedChannelException e);

    void onMycatServerWriteException(MycatSession session, Exception e);

    void onGettingBackend(Session session, String replicaName, String defaultDataBase, Exception e);

    void onCloseMycatSession(MycatSession mycat, boolean normal, String reason);

    //command
    void onCommandStart(MycatSession mycat);

    void onCommandEnd(MycatSession mycat);

    void onSleepCommandStart(MycatSession mycat);

    void onSleepCommandEnd(MycatSession mycat);

    void onQuitCommandStart(MycatSession mycat);

    void onQuitCommandEnd(MycatSession mycat);

    void onQueryCommandStart(MycatSession mycat);

    void onQueryCommandEnd(MycatSession mycat);

    void onInitDbCommandStart(MycatSession mycat);

    void onInitDbCommandEnd(MycatSession mycat);

    void onPingCommandStart(MycatSession mycat);

    void onPingCommandEnd(MycatSession mycat);

    void onFieldListCommandStart(MycatSession mycat);

    void onFieldListCommandEnd(MycatSession mycat);

    void onSetOptionCommandStart(MycatSession mycat);

    void onSetOptionCommandEnd(MycatSession mycat);

    void onPrepareCommandStart(MycatSession mycat);

    void onPrepareCommandEnd(MycatSession mycat);

    void onSendLongDataCommandStart(MycatSession mycat);

    void onSendLongDataCommandEnd(MycatSession mycat);

    void onExecuteCommandStart(MycatSession mycat);

    void onExecuteCommandEnd(MycatSession mycat);

    void onCloseCommandStart(MycatSession mycat);

    void onCloseCommandEnd(MycatSession mycat);

    void onResetCommandStart(MycatSession mycat);

    void onResetCommandEnd(MycatSession mycat);

    void onCreateDbCommandStart(MycatSession mycat);

    void onCreateDbCommandEnd(MycatSession mycat);


    void onDropDbCommandStart(MycatSession mycat);

    void onDropDbCommandEnd(MycatSession mycat);

    void onRefreshCommandStart(MycatSession mycat);

    void onRefreshCommandEnd(MycatSession mycat);

    void onShutdownCommandStart(MycatSession mycat);

    void onStatisticsCommandEnd(MycatSession mycat);

    void onProcessInfoCommandStart(MycatSession mycat);

    void onProcessInfoCommandEnd(MycatSession mycat);

    void onConnectCommandStart(MycatSession mycat);

    void onConnectCommandEnd(MycatSession mycat);

    void onProcessKillCommandStart(MycatSession mycat);

    void onProcessKillCommandEnd(MycatSession mycat);

    void onDebugCommandStart(MycatSession mycat);

    void onDebugCommandEnd(MycatSession mycat);

    void onTimeCommandStart(MycatSession mycat);

    void onTimeCommandEnd(MycatSession mycat);

    void onDelayedInsertCommandStart(MycatSession mycat);

    void onDelayedInsertCommandEnd(MycatSession mycat);

    void onChangeUserCommandStart(MycatSession mycat);

    void onChangeUserCommandEnd(MycatSession mycat);

    void onResetConnectionCommandStart(MycatSession mycat);

    void onResetConnectionCommandEnd(MycatSession mycat);

    void onDaemonCommandStart(MycatSession mycat);

    void onDaemonCommandEnd(MycatSession mycat);

    void onShutdownCommandEnd(MycatSession mycat);

    void onStatisticsCommandStart(MycatSession mycat);

    void onPacketExchangerRead(Session session);

    void onPacketExchangerWrite(Session session);

    void onFetchCommandStart(MycatSession mycat);

    void onFetchCommandEnd(MycatSession mycat);

    void onLoadDataLocalInFileEmptyPacketStart(MycatSession mycat);

    void onLoadDataLocalInFileEmptyPacketEnd(MycatSession mycat);

    void onLoadDataLocalInFileContextStart(MycatSession mycat);

    void onLoadDataLocalInFileContextEnd(MycatSession mycat);

    void onChange2ReadOpts(Session session);

    void onChange2WriteOpts(Session session);

    void onClearReadWriteOpts(Session session);

    void onResultSetEnd(MySQLClientSession mysql);

    void onRouteSQL(MycatSession mycat, String dataSourceName, String sql);
}
