/*-
 * ~~~~~~licensing~~~~~~
 * bridge-profile-manager
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.esb.system.management.bridge.profile.manager;

import com.google.gson.Gson;
import ru.entaxy.esb.system.common.exception.EsbNotFound;
import ru.entaxy.esb.system.jpa.SystemService;
import ru.entaxy.esb.system.jpa.entity.System;
import ru.entaxy.esb.system.management.bridge.profile.manager.dto.BridgeProfileDto;
import ru.entaxy.esb.system.management.bridge.profile.manager.mapper.BridgeProfileMapper;
import ru.entaxy.esb.system.management.bridge.profile.manager.sender.BridgeProfileSender;
import ru.entaxy.esb.system.management.bridge.profile.manager.sender.BridgeProfileType;
import ru.entaxy.esb.system.management.bridge.profile.manager.service.BridgeService;
import ru.entaxy.esb.system.management.bundle.jpa.dto.BundleDto;

import java.util.List;

public class BridgeProfileManagerImpl implements BridgeProfileManager {

    private static final Gson gson = new Gson();

    private BridgeProfileSender bridgeProfileSender;
    private SystemService systemService;
    private BridgeProfileMapper bridgeProfileMapper;
    private BridgeService bridgeService;

    @Override
    public BundleDto installBridgeProfile(BridgeProfileDto bridgeProfileDto) throws Exception {
        System system = systemService.getByUuid(bridgeProfileDto.getProfileUuid());
        systemService.addExportAllowed(system, bridgeProfileDto.getEsbName());
        BundleDto bundleDto;
        try {
            checkOnConnectEsbBridge(bridgeProfileDto.getEsbName());
            bundleDto = gson.fromJson(sendOnOtherEsb(system, bridgeProfileDto.getEsbName(),
                    "create"), BundleDto.class);
        } catch (Exception ex) {
            systemService.removeExportAllowed(system, bridgeProfileDto.getEsbName());
            throw ex;
        }
        return bundleDto;
    }

    @Override
    public BundleDto startBridgeProfile(BridgeProfileDto bridgeProfileDto) throws Exception {
        System system = systemService.getByUuid(bridgeProfileDto.getProfileUuid());
        checkOnConnectEsbBridge(bridgeProfileDto.getEsbName());
        systemService.addExportAllowed(system, bridgeProfileDto.getEsbName());
        BundleDto bundleDto = gson.fromJson(sendOnOtherEsb(system, bridgeProfileDto.getEsbName(),
                "start"), BundleDto.class);
        return bundleDto;
    }

    @Override
    public BundleDto stopBridgeProfile(BridgeProfileDto bridgeProfileDto) throws Exception {
        System system = systemService.getByUuid(bridgeProfileDto.getProfileUuid());
        checkOnConnectEsbBridge(bridgeProfileDto.getEsbName());
        systemService.addExportAllowed(system, bridgeProfileDto.getEsbName());
        BundleDto bundleDto = gson.fromJson(sendOnOtherEsb(system, bridgeProfileDto.getEsbName(),
                "stop"), BundleDto.class);
        return bundleDto;
    }

    @Override
    public BridgeProfileType getBridgeProfile(BridgeProfileDto request) throws Exception {
        System system = systemService.getByUuid(request.getProfileUuid());
        checkOnConnectEsbBridge(request.getEsbName());
        systemService.addExportAllowed(system, request.getEsbName());
        BridgeProfileType response = gson.fromJson(sendOnOtherEsb(system, request.getEsbName(),
                "get"), BridgeProfileType.class);
        return response;
    }

    @Override
    public List<BridgeProfileType> getBridgeProfiles() throws Exception {
        return bridgeProfileMapper.toBridgeProfileTypes(systemService.getFullSystemListByNotOrigin());
    }

    @Override
    public BundleDto uninstallBridgeProfile(BridgeProfileDto bridgeProfileDto) throws Exception {
        System system = systemService.getByUuid(bridgeProfileDto.getProfileUuid());
        checkOnConnectEsbBridge(bridgeProfileDto.getEsbName());
        systemService.removeExportAllowed(system, bridgeProfileDto.getEsbName());
        BundleDto bundleDto = gson.fromJson(sendOnOtherEsb(system, bridgeProfileDto.getEsbName(),
                "uninstall"), BundleDto.class);
        return bundleDto;
    }

    @Override
    public List<String> getListEsb() throws Exception {
        return bridgeService.getEsbList();
    }

    private String sendOnOtherEsb(System system, String exportAllowed, String command) {
        return bridgeProfileSender.sendOnOtherEsb(bridgeProfileMapper.toBridgeProfileType(system),
                exportAllowed, command);
    }

    public void checkOnConnectEsbBridge(String esbName) {
        if (!bridgeService.getEsbList().contains(esbName)) {
            throw new EsbNotFound("ESB not found {" + esbName + "}");
        }
    }

    public void setSystemService(SystemService systemService) {
        this.systemService = systemService;
    }

    public void setBridgeProfileMapper(BridgeProfileMapper bridgeProfileMapper) {
        this.bridgeProfileMapper = bridgeProfileMapper;
    }

    public void setBridgeService(BridgeService bridgeService) {
        this.bridgeService = bridgeService;
    }

    public void setBridgeProfileSender(BridgeProfileSender bridgeProfileSender) {
        this.bridgeProfileSender = bridgeProfileSender;
    }
}
