/*
 * Copyright 2014-2015 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.store.core.impl;

import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent;

import com.google.common.collect.ImmutableSet;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.IAtomicLong;
import com.hazelcast.core.MapEvent;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.store.hz.AbstractHazelcastStore;
import org.onosproject.store.hz.SMap;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.serializers.KryoSerializer;
import org.onlab.util.KryoNamespace;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Simple implementation of the application ID registry using in-memory
 * structures.
 */
@Component(immediate = false, enabled = false)
@Service
public class DistributedApplicationIdStore
        extends AbstractHazelcastStore<AppIdEvent, AppIdStoreDelegate>
        implements ApplicationIdStore {

    protected IAtomicLong lastAppId;
    protected SMap<String, DefaultApplicationId> appIdsByName;

    protected Map<Short, DefaultApplicationId> appIds = new ConcurrentHashMap<>();

    private String listenerId;


    @Override
    @Activate
    public void activate() {
        super.activate();

        this.serializer = new KryoSerializer() {
            @Override
            protected void setupKryoPool() {
                serializerPool = KryoNamespace.newBuilder()
                        .register(KryoNamespaces.API)
                        .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
                        .build();
            }
        };

        lastAppId = theInstance.getAtomicLong("applicationId");

        appIdsByName = new SMap<>(theInstance.<byte[], byte[]>getMap("appIdsByName"), this.serializer);
        listenerId = appIdsByName.addEntryListener((new RemoteAppIdEventHandler()), true);

        primeAppIds();

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        appIdsByName.removeEntryListener(listenerId);
        log.info("Stopped");
    }

    @Override
    public Set<ApplicationId> getAppIds() {
        return ImmutableSet.<ApplicationId>copyOf(appIds.values());
    }

    @Override
    public ApplicationId getAppId(Short id) {
        ApplicationId appId = appIds.get(id);
        if (appId == null) {
            primeAppIds();
            return appIds.get(id);
        }
        return appId;
    }

    @Override
    public ApplicationId getAppId(String name) {
        return appIdsByName.get(name);
    }

    private void primeAppIds() {
        for (DefaultApplicationId appId : appIdsByName.values()) {
            appIds.putIfAbsent(appId.id(), appId);
        }
    }

    @Override
    public ApplicationId registerApplication(String name) {
        DefaultApplicationId appId = appIdsByName.get(name);
        if (appId == null) {
            int id = (int) lastAppId.getAndIncrement();
            appId = putIfAbsent(appIdsByName, name,
                                new DefaultApplicationId(id, name));
        }
        return appId;
    }

    private class RemoteAppIdEventHandler implements EntryListener<String, DefaultApplicationId> {
        @Override
        public void entryAdded(EntryEvent<String, DefaultApplicationId> event) {
            DefaultApplicationId appId = event.getValue();
            appIds.put(appId.id(), appId);
        }

        @Override
        public void entryRemoved(EntryEvent<String, DefaultApplicationId> event) {
        }

        @Override
        public void entryUpdated(EntryEvent<String, DefaultApplicationId> event) {
            entryAdded(event);
        }

        @Override
        public void entryEvicted(EntryEvent<String, DefaultApplicationId> event) {
        }

        @Override
        public void mapEvicted(MapEvent event) {
        }

        @Override
        public void mapCleared(MapEvent event) {
        }
    }
}
