/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.felix.utils.service;

import java.util.Dictionary;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;

public abstract class BaseManagedServiceFactory<T> implements ManagedServiceFactory {

    public static final long DEFAULT_TIMEOUT_BEFORE_INTERRUPT = 30000;

    private final BundleContext context;
    private final String name;
    private final long timeoutBeforeInterrupt;
    private final AtomicBoolean destroyed;
    private final ExecutorService executor;
    private final Map<String, Pair<T, ServiceRegistration>> services;

    public BaseManagedServiceFactory(BundleContext context, String name) {
        this(context, name, DEFAULT_TIMEOUT_BEFORE_INTERRUPT);
    }

    public BaseManagedServiceFactory(BundleContext context, String name, long timeoutBeforeInterrupt) {
        this.context = context;
        this.name = name;
        this.timeoutBeforeInterrupt = timeoutBeforeInterrupt;
        this.destroyed = new AtomicBoolean(false);
        this.executor = Executors.newSingleThreadExecutor();
        this.services = new ConcurrentHashMap<String, Pair<T, ServiceRegistration>>();
    }

    public String getName() {
        return name;
    }

    public void updated(final String pid, final Dictionary properties) throws ConfigurationException {
        if (destroyed.get()) {
            return;
        }
        checkConfiguration(pid, properties);
        executor.submit(new Runnable() {
            public void run() {
                try {
                    internalUpdate(pid, properties);
                } catch (Throwable t) {
                    warn("Error destroying service for ManagedServiceFactory " + getName(), t);
                }
            }
        });
    }

    public void deleted(final String pid) {
        if (destroyed.get()) {
            return;
        }
        executor.submit(new Runnable() {
            public void run() {
                try {
                    internalDelete(pid);
                } catch (Throwable throwable) {
                    warn("Error destroying service for ManagedServiceFactory " + getName(), throwable);
                }
            }
        });
    }

    protected void checkConfiguration(String pid, Dictionary properties) throws ConfigurationException {
        // Do nothing
    }

    protected abstract T doCreate(Dictionary properties) throws Exception;

    protected T doUpdate(T t, Dictionary properties) throws Exception {
        doDestroy(t);
        return doCreate(properties);
    }

    protected abstract void doDestroy(T t) throws Exception;

    protected abstract String[] getExposedClasses(T t);

    private void internalUpdate(String pid, Dictionary properties) {
        Pair<T, ServiceRegistration> pair = services.get(pid);
        if (pair != null) {
            try {
                T t = doUpdate(pair.getFirst(), properties);
                pair.setFirst(t);
                pair.getSecond().setProperties(properties);
            } catch (Throwable throwable) {
                internalDelete(pid);
                warn("Error updating service for ManagedServiceFactory " + getName(), throwable);
            }
        } else {
            if (destroyed.get()) {
                return;
            }
            try {
                T t = doCreate(properties);
                try {
                    if (destroyed.get()) {
                        throw new IllegalStateException("ManagedServiceFactory has been destroyed");
                    }
                    ServiceRegistration registration = context.registerService(getExposedClasses(t), t, properties);
                    services.put(pid, new Pair<T, ServiceRegistration>(t, registration));
                } catch (Throwable throwable1) {
                    try {
                        doDestroy(t);
                    } catch (Throwable throwable2) {
                        // Ignore
                    }
                    throw throwable1;
                }
            } catch (Throwable throwable) {
                warn("Error creating service for ManagedServiceFactory " + getName(), throwable);
            }
        }
    }

    private void internalDelete(String pid) {
        Pair<T, ServiceRegistration> pair = services.remove(pid);
        if (pair != null) {
            try {
                pair.getSecond().unregister();
            } catch (Throwable t) {
                info("Error unregistering service", t);
            }
            try {
                doDestroy(pair.getFirst());
            } catch (Throwable t) {
                info("Error destroying service", t);
            }
        }
    }

    protected abstract void warn(String message, Throwable t);

    protected abstract void info(String message, Throwable t);

    public void destroy() {
        if (destroyed.compareAndSet(false, true)) {
            executor.shutdown();
            try {
                executor.awaitTermination(timeoutBeforeInterrupt, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                throw new RuntimeException("Shutdown interrupted");
            }
            if (!executor.isTerminated()) {
                executor.shutdownNow();
                try {
                    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                } catch (InterruptedException e) {
                    throw new RuntimeException("Shutdown interrupted");
                }
            }

            while (!services.isEmpty()) {
                String pid = services.keySet().iterator().next();
                internalDelete(pid);
            }
        }
    }

    static class Pair<U,V> {
        private U first;
        private V second;
        public Pair(U first, V second) {
            this.first = first;
            this.second = second;
        }
        public U getFirst() {
            return first;
        }
        public V getSecond() {
            return second;
        }
        public void setFirst(U first) {
            this.first = first;
        }
        public void setSecond(V second) {
            this.second = second;
        }
    }

}
