/*
 * Copyright 2015-present 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.slf4j.LoggerFactory.getLogger;

import java.util.Map;
import java.util.Set;
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.KryoNamespace;
import org.onlab.util.Tools;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.AtomicCounter;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageException;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.Versioned;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;

/**
 * ApplicationIdStore implementation on top of {@code AtomicCounter}
 * and {@code ConsistentMap} primitives.
 */
@Component(immediate = true, enabled = true)
@Service
public class ConsistentApplicationIdStore implements ApplicationIdStore {

    private final Logger log = getLogger(getClass());

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StorageService storageService;

    private AtomicCounter appIdCounter;
    private ConsistentMap<String, ApplicationId> registeredIds;
    private Map<String, ApplicationId> nameToAppIdCache = Maps.newConcurrentMap();
    private Map<Short, ApplicationId> idToAppIdCache = Maps.newConcurrentMap();

    private static final Serializer SERIALIZER = Serializer.using(new KryoNamespace.Builder()
                                                                        .register(KryoNamespaces.API)
                                                                        .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
                                                                        .build());

    @Activate
    public void activate() {
        appIdCounter = storageService.getAtomicCounter("onos-app-id-counter");

        registeredIds = storageService.<String, ApplicationId>consistentMapBuilder()
                .withName("onos-app-ids")
                .withSerializer(SERIALIZER)
                .build();

        primeAppIds();

        log.info("Started");
    }

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

    @Override
    public Set<ApplicationId> getAppIds() {
        // TODO: Rework this when we have notification support in ConsistentMap.
        primeAppIds();
        return ImmutableSet.copyOf(nameToAppIdCache.values());
    }

    @Override
    public ApplicationId getAppId(Short id) {
        if (!idToAppIdCache.containsKey(id)) {
            primeAppIds();
        }
        return idToAppIdCache.get(id);
    }

    @Override
    public ApplicationId getAppId(String name) {
        ApplicationId appId = nameToAppIdCache.computeIfAbsent(name, key -> {
            Versioned<ApplicationId> existingAppId = registeredIds.get(key);
            return existingAppId != null ? existingAppId.value() : null;
        });
        if (appId != null) {
            idToAppIdCache.putIfAbsent(appId.id(), appId);
        }
        return appId;
    }

    @Override
    public ApplicationId registerApplication(String name) {
        ApplicationId appId = nameToAppIdCache.computeIfAbsent(name, key -> {
            Versioned<ApplicationId> existingAppId = registeredIds.get(name);
            if (existingAppId == null) {
                int id = Tools.retryable(appIdCounter::incrementAndGet, StorageException.class, 1, 2000)
                              .get()
                              .intValue();
                DefaultApplicationId newAppId = new DefaultApplicationId(id, name);
                existingAppId = registeredIds.putIfAbsent(name, newAppId);
                if (existingAppId != null) {
                    return existingAppId.value();
                } else {
                    return newAppId;
                }
            } else {
                return existingAppId.value();
            }
        });
        idToAppIdCache.putIfAbsent(appId.id(), appId);
        return appId;
    }

    private void primeAppIds() {
        registeredIds.values()
                     .stream()
                     .map(Versioned::value)
                     .forEach(appId -> {
                         nameToAppIdCache.putIfAbsent(appId.name(), appId);
                         idToAppIdCache.putIfAbsent(appId.id(), appId);
                     });
    }
}
