/*-
 * ~~~~~~licensing~~~~~~
 * system-management-api
 * ==========
 * 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;

import ru.entaxy.esb.system.core.template.Template;
import ru.entaxy.esb.system.management.bridge.profile.manager.BridgeProfileManager;
import ru.entaxy.esb.system.management.bridge.profile.manager.dto.BridgeProfileDto;
import ru.entaxy.esb.system.management.bundle.jpa.dto.BundleStatus;
import ru.entaxy.esb.system.management.connector.manager.ConnectorManager;
import ru.entaxy.esb.system.management.connector.manager.dto.ConnectorDto;
import ru.entaxy.esb.system.management.mapper.Mapper;
import ru.entaxy.esb.system.management.permission.manager.PermissionManager;
import ru.entaxy.esb.system.management.permission.manager.dto.PermissionDto;
import ru.entaxy.esb.system.management.profile.manager.ProfileManager;
import ru.entaxy.esb.system.management.profile.manager.dto.ProfileDto;
import ru.entaxy.esb.system.management.route.manager.RouteManager;
import ru.entaxy.esb.system.management.soap.*;

import javax.jws.WebService;

@WebService(endpointInterface = "ru.entaxy.esb.system.management.soap.SystemManagementService",
        targetNamespace = "http://www.entaxy.ru/system-management-service/",
        serviceName = "SystemManagementServiceImpl"
)
public class SystemManagementServiceImpl implements SystemManagementService {

    private ProfileManager profileManager;
    private BridgeProfileManager bridgeProfileManager;
    private ConnectorManager connectorManager;
    private PermissionManager permissionManager;

    private Mapper mapper;

    @Override
    public boolean createProfile(CreateProfileType createProfileType, String createdBy) {
        try {
            validateProfileName(createProfileType.getProfileName());
            ProfileDto profileDto = mapper.toProfileDto(createProfileType);
            profileDto.setCreatedBy(createdBy);
            return (BundleStatus.ACTIVE.equals(profileManager.installProfile(profileDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean startProfile(ProfileType profileType, String createdBy) {
        try {
            ProfileDto profileDto = mapper.toProfileDto(profileType);
            profileDto.setCreatedBy(createdBy);
            return (BundleStatus.ACTIVE.equals(profileManager.startProfile(profileDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean stopProfile(ProfileType profileType, String createdBy) {
        try {
            ProfileDto profileDto = mapper.toProfileDto(profileType);
            profileDto.setCreatedBy(createdBy);
            return (BundleStatus.RESOLVED.equals(profileManager.stopProfile(profileDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean removeProfile(ProfileType profileType, String createdBy) {
        try {
            profileManager.uninstallProfile(mapper.toProfileDto(profileType));
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public FullProfileType getProfile(ProfileType profileType, String createdBy) {
        try {
            return mapper.toFullProfileType(profileManager.getProfile(mapper.toProfileDto(profileType)));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public ListFullProfileType getProfiles(ListProfileRequest request, String createdBy) {
        try {
            return mapper.toListFullProfileType(profileManager.getProfiles());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean createConnector(CreateConnectorType connectorGeneratorType, String createdBy) {
        try {
            ConnectorDto connectorDto = mapper.toConnectorDto(connectorGeneratorType);
            connectorDto.setCreatedBy(createdBy);
            return (BundleStatus.ACTIVE.equals(connectorManager.installConnector(connectorDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public ListConnectorType getConnectors(ListConnectorRequest request, String createdBy) {
        return mapper.toListConnectorType(connectorManager.getListConnector());
    }

    @Override
    public boolean startConnector(GetConnectorType getConnectorType, String createdBy) {
        try {
            ConnectorDto connectorDto = mapper.toConnectorDto(getConnectorType);
            connectorDto.setCreatedBy(createdBy);
            return (BundleStatus.ACTIVE.equals(connectorManager.startConnector(connectorDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean stopConnector(GetConnectorType getConnectorType, String createdBy) {
        try {
            ConnectorDto connectorDto = mapper.toConnectorDto(getConnectorType);
            connectorDto.setCreatedBy(createdBy);
            return (BundleStatus.RESOLVED.equals(connectorManager.stopConnector(connectorDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean createPermission(PermissionType request, String createdBy) {
        permissionManager.createPermission(mapper.toPermissionDto(request));
        return true;
    }

    @Override
    public ListProfileType getPermissionsByObject(ProfileType request, String createdBy) {
        try {
            return mapper.toListProfileType(profileManager.getPermissionsByObject(request.getUuid()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public ListProfileType getPermissionsBySubject(ProfileType request, String createdBy) {
        try {
            return mapper.toListProfileType(profileManager.getPermissionsBySubject(request.getUuid()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean removePermission(PermissionType request, String createdBy) {
        permissionManager.removePermission(mapper.toPermissionDto(request));
        return true;
    }

    @Override
    public boolean createPermissionForSubject(PermissionForSubjectType request, String createdBy) {
        for (String objectUuid : request.getObjectUuid()) {
            permissionManager.createPermission(new PermissionDto(objectUuid, request.getSubjectUuid()));
        }
        return true;
    }

    @Override
    public boolean createPermissionForObject(PermissionForObjectType request, String createdBy) {
        for (String subjectUuid : request.getSubjectUuid()) {
            permissionManager.createPermission(new PermissionDto(request.getObjectUuid(), subjectUuid));
        }
        return true;
    }

    @Override
    public boolean removeConnector(GetConnectorType getConnectorType, String createdBy) {
        try {
            return (BundleStatus.UNINSTALL.equals(connectorManager.uninstallConnector(
                    mapper.toConnectorDto(getConnectorType)).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public ListBridgeProfileType getBridgeProfiles(GetBridgeProfilesRequest request, String createdBy) {
        try {
            return mapper.toListBridgeProfileType(bridgeProfileManager.getBridgeProfiles());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean createBridgeProfile(BridgeProfileType bridgeProfileType, String createdBy) {
        try {
            BridgeProfileDto bridgeProfileDto = mapper.toBridgeProfileDto(bridgeProfileType);
            bridgeProfileDto.setCreatedBy(createdBy);
            return (BundleStatus.ACTIVE.equals(bridgeProfileManager.installBridgeProfile(bridgeProfileDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public FullBridgeProfileType getBridgeProfile(BridgeProfileType request, String createdBy) {
        try {
            return mapper.toFullBridgeProfileType(bridgeProfileManager.getBridgeProfile(mapper.toBridgeProfileDto(request)));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean startBridgeProfile(BridgeProfileType bridgeProfileType, String createdBy) {
        try {
            BridgeProfileDto bridgeProfileDto = mapper.toBridgeProfileDto(bridgeProfileType);
            bridgeProfileDto.setCreatedBy(createdBy);
            return (BundleStatus.ACTIVE.equals(bridgeProfileManager.startBridgeProfile(bridgeProfileDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean stopBridgeProfile(BridgeProfileType bridgeProfileType, String createdBy) {
        try {
            BridgeProfileDto bridgeProfileDto = mapper.toBridgeProfileDto(bridgeProfileType);
            bridgeProfileDto.setCreatedBy(createdBy);
            return (BundleStatus.RESOLVED.equals(bridgeProfileManager.stopBridgeProfile(bridgeProfileDto).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public boolean removeBridgeProfile(BridgeProfileType bridgeProfileType, String createdBy) {
        try {
            return (BundleStatus.UNINSTALL.equals(bridgeProfileManager.uninstallBridgeProfile(
                    mapper.toBridgeProfileDto(bridgeProfileType)).getStatus()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public ListTemplateType getTemplates(ListTemplateRequest request, String createdBy) {
        ListTemplateType listTemplateType = new ListTemplateType();
        for (Template template : connectorManager.getTemplates()) {
            listTemplateType.getTemplate().add(mapper.toTemplateType(template));
        }
        return listTemplateType;
    }

    @Override
    public TemplateType getTemplate(GetTemplate request, String createdBy) {
        return mapper.toTemplateType(connectorManager.getTemplate(request.getTemplateName()));
    }

    @Override
    public ListEsbType getListEsb(ListEsbRequest request, String createdBy) {
        try {
            ListEsbType listEsbType = new ListEsbType();
            for (String s : bridgeProfileManager.getListEsb()) {
                listEsbType.getEsbName().add(s);
            }
            return listEsbType;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private void validateProfileName(String data) throws Exception {
        if (!data.matches("([A-Za-z][A-Za-z0-9_\\-]*)"))
            throw new IllegalArgumentException("Invalid data format in {" + data + "}");
    }

    public void setConnectorManager(ConnectorManager connectorManager) {
        this.connectorManager = connectorManager;
    }

    public void setProfileManager(ProfileManager profileManager) {
        this.profileManager = profileManager;
    }

    public void setBridgeProfileManager(BridgeProfileManager bridgeProfileManager) {
        this.bridgeProfileManager = bridgeProfileManager;
    }

    public void setPermissionManager(PermissionManager permissionManager) {
        this.permissionManager = permissionManager;
    }

    public void setMapper(Mapper mapper) {
        this.mapper = mapper;
    }
}
