package com.atlassian.bitbucket.internal.webhook;

import com.atlassian.bitbucket.webhook.WebHookListenerOwnerResolver;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class DefaultWebHookListenerOwnerResolverRegistry implements WebHookListenerOwnerResolverRegistry {
    private final BundleContext bundleContext;
    private final List<WebHookListenerOwnerResolver> resolvers;

    private ServiceTracker<WebHookListenerOwnerResolver, WebHookListenerOwnerResolver> serviceTracker;

    public DefaultWebHookListenerOwnerResolverRegistry(BundleContext bundleContext) {
        this.resolvers = new CopyOnWriteArrayList<>();
        this.bundleContext = bundleContext;
    }

    public void destroy() {
        if (serviceTracker != null) {
            serviceTracker.close();
        }
    }

    public void initialize() {
        serviceTracker = new ServiceTracker<>(bundleContext, WebHookListenerOwnerResolver.class.getName(), new RegisteringCustomizer());
        serviceTracker.open();
    }

    @Nonnull
    @Override
    public List<WebHookListenerOwnerResolver> getResolvers() {
        return new ArrayList<>(resolvers);
    }

    private class RegisteringCustomizer implements ServiceTrackerCustomizer<WebHookListenerOwnerResolver, WebHookListenerOwnerResolver> {

        @Override
        public WebHookListenerOwnerResolver addingService(ServiceReference<WebHookListenerOwnerResolver> reference) {
            WebHookListenerOwnerResolver resolver = bundleContext.getService(reference);
            resolvers.add(resolver);
            return resolver;
        }

        @Override
        public void modifiedService(ServiceReference<WebHookListenerOwnerResolver> reference, WebHookListenerOwnerResolver service) {
            // ignore
        }

        @Override
        public void removedService(ServiceReference<WebHookListenerOwnerResolver> reference, WebHookListenerOwnerResolver service) {
            resolvers.remove(service);
            bundleContext.ungetService(reference);
        }
    }
}
