/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.openstacknetworking.impl;

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.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.openstacknetworking.api.InstancePortAdminService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type;
import org.onosproject.openstacknetworking.api.PreCommitPortService;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;

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

import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of pre-commit service.
 */
@Service
@Component(immediate = true)
public class PreCommitPortManager implements PreCommitPortService {

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

    private static final KryoNamespace SERIALIZER_PRE_COMMIT = KryoNamespace.newBuilder()
            .register(KryoNamespaces.API)
            .register(OpenstackNetworkEvent.Type.class)
            .build();

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

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

    private ConsistentMap<String, Map<Type, Set<String>>> store;

    @Activate
    protected void activate() {

        ApplicationId appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);

        store = storageService.<String, Map<Type, Set<String>>>consistentMapBuilder()
                .withSerializer(Serializer.using(SERIALIZER_PRE_COMMIT))
                .withName("openstack-pre-commit-store")
                .withApplicationId(appId)
                .build();

        log.info("Started");
    }

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

    @Override
    public void subscribePreCommit(String portId, Type eventType, String className) {
        store.computeIfAbsent(portId, s -> new HashMap<>());

        store.compute(portId, (k, v) -> {

            if (className == null || className.isEmpty()) {
                return null;
            }

            Objects.requireNonNull(v).computeIfAbsent(eventType, s -> new HashSet<>());


            Objects.requireNonNull(v).compute(eventType, (i, j) -> {
                Objects.requireNonNull(j).add(className);
                return j;
            });

            return v;
        });
    }

    @Override
    public void unsubscribePreCommit(String portId, Type eventType,
                                     InstancePortAdminService service, String className) {

        store.computeIfPresent(portId, (k, v) -> {

            if (className == null || className.isEmpty()) {
                return null;
            }

            Objects.requireNonNull(v).computeIfPresent(eventType, (i, j) -> {
                Objects.requireNonNull(j).remove(className);
                return j;
            });

            return v;
        });

        if (subscriberCountByEventType(portId, eventType) == 0) {
            service.removeInstancePort(portId);
        }
    }

    @Override
    public int subscriberCountByEventType(String portId, Type eventType) {

        Map<Type, Set<String>> typeMap = store.asJavaMap().get(portId);

        if (typeMap == null || typeMap.isEmpty()) {
            return 0;
        }

        if (typeMap.get(eventType) == null || typeMap.get(eventType).isEmpty()) {
            return 0;
        }

        return typeMap.get(eventType).size();
    }

    @Override
    public int subscriberCount(String portId) {

        Map<Type, Set<String>> typeMap = store.asJavaMap().get(portId);

        if (typeMap == null || typeMap.isEmpty()) {
            return 0;
        }

        return typeMap.values().stream()
                .filter(Objects::nonNull)
                .map(Set::size)
                .reduce(0, Integer::sum);
    }
}
