/*-
 * ~~~~~~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.recipient;

import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ru.entaxy.esb.system.jpa.SystemService;
import ru.entaxy.esb.system.jpa.entity.System;
import ru.entaxy.esb.system.management.bridge.profile.manager.mapper.BridgeProfileMapper;
import ru.entaxy.esb.system.management.bridge.profile.manager.sender.BridgeProfileType;
import ru.entaxy.esb.system.management.bundle.jpa.dto.BundleDto;
import ru.entaxy.esb.system.management.bundle.jpa.dto.BundleStatus;
import ru.entaxy.esb.system.management.bundle.manager.BundleManager;

import java.io.IOException;
import java.util.HashMap;

public class BridgeProfileRecipientManagerImpl implements BridgeProfileRecipientManager {

	private static final Log LOG = LogFactory.getLog(BridgeProfileRecipientManagerImpl.class);
	
    private static final String BRIDGE_PROFILE = "bridge-profile";
    private static final String ORIGIN = "origin";
    private static final Gson gson = new Gson();

    private boolean isRestoreFromDB;

    private BundleManager bundleManager;
    private SystemService systemService;
    private BridgeProfileMapper bridgeProfileMapper;

    @Override
    public String installBridgeProfile(String json, String origin) throws Exception {
        System system = createSystem(gson.fromJson(json, BridgeProfileType.class), origin);
        BundleDto bundle = bundleManager.installAndStartBundle(system.getName(), BRIDGE_PROFILE,
                String.valueOf(system.getVersion()), getParam(origin));
        systemService.setBundleEntity(system, bridgeProfileMapper.toBundleEntity(bundle));
        return gson.toJson(bundle);
    }

    @Override
    public String startBridgeProfile(String json, String origin) throws Exception {
        BridgeProfileType bridgeProfileType = gson.fromJson(json, BridgeProfileType.class);
        System system = systemService.getByUuid(bridgeProfileType.getUuid());
        BundleDto bundle = bundleManager.startBundle(bridgeProfileMapper.toBundleDto(system.getBundleEntity()));
        systemService.setBundleEntity(system, bridgeProfileMapper.toBundleEntity(bundle));
        return gson.toJson(bundle);
    }

    @Override
    public String stopBridgeProfile(String json, String origin) throws Exception {
        BridgeProfileType bridgeProfileType = gson.fromJson(json, BridgeProfileType.class);
        System system = systemService.getByUuid(bridgeProfileType.getUuid());
        BundleDto bundle = bundleManager.stopBundle(bridgeProfileMapper.toBundleDto(system.getBundleEntity()));
        systemService.setBundleEntity(system, bridgeProfileMapper.toBundleEntity(bundle));
        return gson.toJson(bundle);
    }

    @Override
    public String getBridgeProfile(String json, String origin) throws Exception {
        BridgeProfileType bridgeProfileType = gson.fromJson(json, BridgeProfileType.class);
        System system = systemService.getByUuid(bridgeProfileType.getUuid());
        return gson.toJson(bridgeProfileMapper.toBridgeProfileType(system));
    }

    @Override
    public String uninstallBridgeProfile(String json, String origin) throws Exception {
        BridgeProfileType bridgeProfileType = gson.fromJson(json, BridgeProfileType.class);
        System system = systemService.getByUuid(bridgeProfileType.getUuid());
        bundleManager.uninstallBundle(system.getName(), BRIDGE_PROFILE,
                String.valueOf(system.getVersion()));
        systemService.remove(system);
        return gson.toJson(new BundleDto(system.getName(), BundleStatus.UNINSTALL));
    }

    private HashMap<String, String> getParam(String origin) {
        HashMap<String, String> param = new HashMap<>();
        param.put(ORIGIN, origin);
        return param;
    }

    private System createSystem(BridgeProfileType bridgeProfileType, String origin) {
        System system = bridgeProfileMapper.toSystemEntity(bridgeProfileType);
        system.setOrigin(origin);
        system.setBundleEntity(null);
        return systemService.create(system);
    }
    
    @Override
	public void restore() throws Exception {
        if (!isRestoreFromDB)
            return;
		for (System system : systemService.getSystemList()) {
			if  (system.getOrigin() != null && !system.getOrigin().isEmpty())  {
				try {
					LOG.info("Restore bridge profile of system " + system.getName());
					bundleManager.restore(bridgeProfileMapper.toBundleDto(system.getBundleEntity()));
				} catch (IOException e) {
					LOG.warn("Recreate bridge profile of system " + system.getName());
					restoreProfile(system);
				}
			} else {
				LOG.info("No bridge profile founded in system");
			}
		}
	}
    
    private void restoreProfile(System system) throws Exception {
		BundleDto bundle = bundleManager.installBundle(system.getName(), BRIDGE_PROFILE,
				String.valueOf(system.getVersion()), getParam(system.getOrigin()));
		
		bundle.setStatus(bridgeProfileMapper.toBundleDto(system.getBundleEntity()).getStatus());
		
		bundleManager.checkCurrentBundleStatus(bundle);
		
		systemService.setBundleEntity(system, bridgeProfileMapper.toBundleEntity(bundle));
	}

    public void setBundleManager(BundleManager bundleManager) {
        this.bundleManager = bundleManager;
    }

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

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

    public void setIsRestoreFromDB(String isRestoreFromDB) {
        this.isRestoreFromDB = Boolean.parseBoolean(isRestoreFromDB);
    }
}
