/*
 * Copyright 2014 Open Networking Laboratory
 *
 * Licensed 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.onlab.onos.net.provider;

import com.google.common.collect.ImmutableSet;
import org.onlab.onos.net.DeviceId;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * Base implementation of provider registry.
 *
 * @param <P> type of the information provider
 * @param <S> type of the provider service
 */
public abstract class AbstractProviderRegistry<P extends Provider, S extends ProviderService<P>>
        implements ProviderRegistry<P, S> {

    private final Map<ProviderId, P> providers = new HashMap<>();
    private final Map<ProviderId, S> services = new HashMap<>();
    private final Map<String, P> providersByScheme = new HashMap<>();

    /**
     * Creates a new provider service bound to the specified provider.
     *
     * @param provider provider
     * @return provider service
     */
    protected abstract S createProviderService(P provider);

    @Override
    public synchronized S register(P provider) {
        checkNotNull(provider, "Provider cannot be null");
        checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id());

        // If the provider is a primary one, check for a conflict.
        ProviderId pid = provider.id();
        checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
                   "A primary provider with id %s is already registered",
                   providersByScheme.get(pid.scheme()));

        S service = createProviderService(provider);
        services.put(provider.id(), service);
        providers.put(provider.id(), provider);

        // Register the provider by URI scheme only if it is not ancillary.
        if (!pid.isAncillary()) {
            providersByScheme.put(pid.scheme(), provider);
        }

        return service;
    }

    @Override
    public synchronized void unregister(P provider) {
        checkNotNull(provider, "Provider cannot be null");
        S service = services.get(provider.id());
        if (service != null && service instanceof AbstractProviderService) {
            ((AbstractProviderService) service).invalidate();
            services.remove(provider.id());
            providers.remove(provider.id());
            if (!provider.id().isAncillary()) {
                providersByScheme.remove(provider.id().scheme());
            }
        }
    }

    @Override
    public synchronized Set<ProviderId> getProviders() {
        return ImmutableSet.copyOf(services.keySet());
    }

    /**
     * Returns the provider registered with the specified provider ID.
     *
     * @param providerId provider identifier
     * @return provider
     */
    protected synchronized P getProvider(ProviderId providerId) {
        return providers.get(providerId);
    }

    /**
     * Returns the provider for the specified device ID based on URI scheme.
     *
     * @param deviceId device identifier
     * @return provider bound to the URI scheme
     */
    protected synchronized P getProvider(DeviceId deviceId) {
        return providersByScheme.get(deviceId.uri().getScheme());
    }

}
