import { Api } from './api';
import { Connection, TestRequest, ConnectionPoolType, SocketResult } from './crud.typings';
import { requestGet, requestDelete, requestPost, requestPut } from './crud.service';
import { editStatusEvent, errorCode } from '@constants/env';

export class DecisionApi implements Api {
    isDec = true;

    getConnectionlist(): Promise<{data?: Connection[]}> {
        return requestGet('list', {});
    }

    deleteConnection(connectionName: string) {
        return requestDelete('', {
            connectionName,
        });
    }

    addConnection(data: Connection) {
        const form = {
            ...data,
            connectionId: data.connectionId || data.connectionName,
            connectionData : JSON.stringify(data.connectionData),
        };
        
        return requestPost('', form);
    }

    updateConnection(data: Connection) {
        const form = {
            ...data,
            connectionData : JSON.stringify(data.connectionData),
        };
        
        return requestPut('', form);
    }

    testConnection(data: Connection): Promise<TestRequest> {
        const form = {
            ...data,
            connectionData : JSON.stringify(data.connectionData),
        };
        
        return requestPost('test', form);
    }

    getConnectionPool(name: string): Promise<{data?: ConnectionPoolType}> {
        return requestGet(`pool/info?connectionName=${encodeURI(name)}`, {});
    }

    getConnectionStatus(name: string): Promise<SocketResult> {
        return this.sendEditStatusEvent(name, editStatusEvent.OPEN).then(re => {
            if (re.errorCode) {
                let errorMessage = '';
                switch (re.errorCode) {
                    case errorCode.CONNECTION_DELETED:
                        errorMessage = 'Dec-Dcm_Connection_Deleted';
                        break;
                    case errorCode.CONNECTION_UNDER_EDIT:
                        errorMessage = 'Dec-Dcm_Connection_Is_Using';
                        break;
                    default:
                        errorMessage = re.errorMsg;
                        break;
                }
                BI.Msg.toast(BI.i18nText(errorMessage, re.errorMsg), {
                    level: 'error',
                });
                throw re;
            } else {
                return re;
            }
        });
    }

    shutdownConnectionStatus(name: string): Promise<SocketResult> {
        return this.sendEditStatusEvent(name, editStatusEvent.SHUTDOWN);
    }

    getSocketStatus(): boolean {
        if (Dec) {
            return Dec.socket.connected;
        }
        
        return false;
    }

    isDriverError(errorCode: string) {
        if (Dec) {
            return DecCst.ErrorCode.LACK_DRIVER === errorCode;
        }
        
        return false;
    }

    private sendEditStatusEvent(name: string, type: string): Promise<SocketResult> {
        return new Promise(resolve => {
            if (Dec && Dec.socket.connected) {
                Dec.socket.emit(type, BI.encode(name), (re: any) => {
                    resolve(re);
                });
            } else {
                resolve({ data: 'success' });
            }
        });
    }
}