/*
 * 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.onosproject.net.provider;

import com.google.common.collect.ImmutableSet;
import org.onosproject.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());
    }

}
