/*-
 * ~~~~~~licensing~~~~~~
 * test-producers
 * ==========
 * 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.base.objects.service.tracker;

import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.entaxy.platform.base.objects.EntaxyObject;
import ru.entaxy.platform.base.objects.service.impl.EntaxyObjectServiceImpl;
import ru.entaxy.platform.base.objects.service.impl.TrackedEntaxyObject;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.osgi.bundle.BundleCapabilityHelper;
import ru.entaxy.platform.base.support.osgi.bundle.CapabilityDescriptor;
import ru.entaxy.platform.base.support.osgi.tracker.UniformBundleTrackerCustomizer;

public class TrackedEntaxyObjectCustomizer extends UniformBundleTrackerCustomizer<List<TrackedEntaxyObject>> {

    private static final Logger log = LoggerFactory.getLogger(TrackedEntaxyObjectCustomizer.class);

    protected EntaxyObjectServiceImpl objectServiceImpl;

    public TrackedEntaxyObjectCustomizer(EntaxyObjectServiceImpl objectServiceImpl) {
        super();
        this.objectServiceImpl = objectServiceImpl;
    }

    @Override
    protected List<TrackedEntaxyObject> createManagedObject(Bundle bundle, BundleEvent event,
            Map<String, List<?>> filterResults) {

        log.debug("\n\tPROCESS BUNDLE: [{}]; tracker: [{}]", bundle.getBundleId(), this);

        List<TrackedEntaxyObject> result = new ArrayList<>();

        String objectsHeader = bundle.getHeaders().get(EntaxyObject.HEADERS.GENERATED_OBJECTS);
        String configHeader = bundle.getHeaders().get(EntaxyObject.HEADERS.GENERATED_OBJECTS_CONFIG);

        String[] objects = objectsHeader.split(",");
        String[] configs = configHeader.split(",");

        BundleCapabilityHelper capabilityHelper = new BundleCapabilityHelper(bundle);

        for (int i = 0; i < objects.length; i++) {

            String[] objectData = objects[i].split(":");
            String configuration = configs[i];
            if (CommonUtils.isValid(configuration)) {
                byte[] bytes = Base64.getDecoder().decode(configuration);
                configuration = new String(bytes);
            } else {
                configuration = "{}";
            }

            String scope = EntaxyObject.OBJECT_SCOPE.PUBLIC;

            TrackedEntaxyObject obj;
            if (objectData.length > 2)
                scope = objectData[2];
            obj = TrackedEntaxyObject.create(
                    objectServiceImpl.getBundleContext(), objectData[0], objectData[1], scope);

            CapabilityDescriptor capability = capabilityHelper.findObjectDeclaration(objectData[0], objectData[1]);
            if (capability != null) {
                obj.setProvided(true);
                obj.displayName(capability.getAttributes().getOrDefault(EntaxyObject.CAPABILITIES.ATTR_DISPLAY_NAME, "")
                        .toString());
                obj.owner(capability.getAttributes().getOrDefault(EntaxyObject.CAPABILITIES.ATTR_OWNER, "")
                        .toString());
                obj.scope(capability.getAttributes().getOrDefault(EntaxyObject.CAPABILITIES.ATTR_SCOPE, scope)
                        .toString());
                Object relationData = capability.getAttributes().get(EntaxyObject.CAPABILITIES.ATTR_RELATION);
                if (relationData != null) {
                    if (relationData instanceof List) {
                        List relationList = (List) relationData;
                        for (Object relation : relationList)
                            if (relation != null)
                                obj.relationDescription(relation.toString());
                    } else if (relationData instanceof String)
                        obj.relationDescription((String) relationData);
                }
            }

            obj.bundle(bundle).configuration(configuration);
            result.add(obj);
        }

        return result;
    }

    @Override
    synchronized public List<TrackedEntaxyObject> addingBundle(Bundle bundle, BundleEvent event) {
        if (listener != null) {
            synchronized (listener) {
                return super.addingBundle(bundle, event);
            }
        }
        return super.addingBundle(bundle, event);
    }
}
