/*-
 * ~~~~~~licensing~~~~~~
 * object-management
 * ==========
 * 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.platform.core.management.object.impl;

import java.util.Arrays;
import java.util.stream.Collectors;

import ru.entaxy.esb.platform.base.management.core.ManagementCore;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.management.object.EntaxyRuntimeItemMBean;
import ru.entaxy.platform.core.management.object.EntaxyRuntimeObjectContainerMBean;
import ru.entaxy.platform.core.management.object.EntaxyRuntimeObjectMBean;

public class MBeanUtils {


    public static EntaxyRuntimeItemMBeanInfo<?> createMBeanInfo(EntaxyRuntimeItemMBean mBean) {
        if (EntaxyRuntimeObjectMBean.class.isAssignableFrom(mBean.getMBeanClass())) {
            EntaxyRuntimeObjectMBeanInfo mBeanInfo = new EntaxyRuntimeObjectMBeanInfo(
                    ((EntaxyRuntimeObjectMBean) mBean).getRuntimeObject());
            mBeanInfo.createHolder((EntaxyRuntimeObjectMBean) mBean);
            return mBeanInfo;
        } else {
            EntaxyRuntimeObjectContainerMBeanInfo mBeanInfo = new EntaxyRuntimeObjectContainerMBeanInfo();
            mBeanInfo.createHolder((EntaxyRuntimeObjectContainerMBean) mBean);
            return mBeanInfo;
        }
    }

    public static String calculateJmxObjectName(EntaxyRuntimeItemMBean mbean) {
        return calculateJmxObjectName(mbean, EntaxyRuntimeItemMBean.JMX_SUBPATH_QUALIFIER);
    }

    public static String calculateJmxObjectName(EntaxyRuntimeItemMBean mbean, String subPathQualifier) {
        String finalName = mbean.getJMXSubQualifier();
        EntaxyRuntimeItemMBean currentMbean = mbean.getParentMBean();
        String parentSubPath = mbean.getParentSubPath();

        String levelPlaceholderConstant = "@LEVEL@";

        finalName = finalName.replace(EntaxyRuntimeItemMBean.JMX_SUBQUALIFIER_AUTO,
                subPathQualifier.concat("_").concat(levelPlaceholderConstant));

        while (currentMbean != null) {
            String newName = currentMbean.getJMXSubQualifier();
            if (CommonUtils.isValid(parentSubPath)) {
                // we must create unique, but idempotent set of keys
                // as a key we'll use subPathQualifier with level index
                String subpath = Arrays.asList(parentSubPath.split("/"))
                        .stream()
                        .map(s -> subPathQualifier.concat("_").concat(levelPlaceholderConstant).concat("=").concat(s))
                        .collect(Collectors.joining(","));
                if (CommonUtils.isValid(subpath))
                    newName = newName.concat(",").concat(subpath);
            }

            finalName = newName.concat(",").concat(finalName);
            parentSubPath = currentMbean.getParentSubPath();
            currentMbean = currentMbean.getParentMBean();
        }

        // replace placeholder with overall level value
        String[] splitted = finalName.split(",");
        for (int i = 0; i < splitted.length; i++) {
            splitted[i] = splitted[i].replace(levelPlaceholderConstant, "" + i);
        }
        finalName = Arrays.asList(splitted).stream().collect(Collectors.joining(","));

        return finalName;
    }

    public static String addNamespace(String qualifier) {
        if (qualifier.contains(":"))
            return qualifier;
        return ManagementCore.ENTAXY_JMX_DOMAIN.concat(":").concat(qualifier);
    }

}
