/*
 * Copyright 2017-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.ofagent.impl;

import com.google.common.collect.ImmutableSet;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.ofagent.api.OFAgent;
import org.onosproject.ofagent.api.OFAgentEvent;
import org.onosproject.ofagent.api.OFAgentEvent.Type;
import org.onosproject.ofagent.api.OFAgentStore;
import org.onosproject.ofagent.api.OFAgentStoreDelegate;
import org.onosproject.ofagent.api.OFController;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.MapEvent;
import org.onosproject.store.service.MapEventListener;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.Versioned;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;

import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.ofagent.api.OFAgent.State.STARTED;
import static org.onosproject.ofagent.api.OFAgentEvent.Type.OFAGENT_CONTROLLER_ADDED;
import static org.onosproject.ofagent.api.OFAgentEvent.Type.OFAGENT_CONTROLLER_REMOVED;
import static org.onosproject.ofagent.api.OFAgentEvent.Type.OFAGENT_STARTED;
import static org.onosproject.ofagent.api.OFAgentEvent.Type.OFAGENT_STOPPED;
import static org.onosproject.ofagent.api.OFAgentService.APPLICATION_NAME;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of the {@link OFAgentStore} with consistent map.
 */
@Component(immediate = true, service = OFAgentStore.class)
public class DistributedOFAgentStore extends AbstractStore<OFAgentEvent, OFAgentStoreDelegate>
        implements OFAgentStore {

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

    private static final String ERR_NOT_FOUND = " does not exist";
    private static final String ERR_DUPLICATE = " already exists";

    private static final KryoNamespace SERIALIZER_OFAGENT = KryoNamespace.newBuilder()
            .register(KryoNamespaces.API)
            .register(OFAgent.class)
            .register(OFAgent.State.class)
            .register(NetworkId.class)
            .register(TenantId.class)
            .register(DefaultOFAgent.class)
            .register(OFController.class)
            .register(DefaultOFController.class)
            .build();

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

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

    private final ExecutorService eventExecutor = newSingleThreadExecutor(
            groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
    private final MapEventListener<NetworkId, OFAgent> ofAgentMapListener = new OFAgentMapListener();

    private ConsistentMap<NetworkId, OFAgent> ofAgentStore;

    @Activate
    protected void activate() {
        ApplicationId appId = coreService.registerApplication(APPLICATION_NAME);
        ofAgentStore = storageService.<NetworkId, OFAgent>consistentMapBuilder()
                .withSerializer(Serializer.using(SERIALIZER_OFAGENT))
                .withName("ofagentstore")
                .withApplicationId(appId)
                .build();
        ofAgentStore.addListener(ofAgentMapListener);

        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        ofAgentStore.removeListener(ofAgentMapListener);
        eventExecutor.shutdown();

        log.info("Stopped");
    }

    @Override
    public void createOfAgent(OFAgent ofAgent) {
        ofAgentStore.compute(ofAgent.networkId(), (id, existing) -> {
            final String error = ofAgent.networkId() + ERR_DUPLICATE;
            checkArgument(existing == null, error);
            return ofAgent;
        });
    }

    @Override
    public void updateOfAgent(OFAgent ofAgent) {
        ofAgentStore.compute(ofAgent.networkId(), (id, existing) -> {
            final String error = ofAgent.networkId() + ERR_NOT_FOUND;
            checkArgument(existing != null, error);
            return ofAgent;
        });
    }

    @Override
    public OFAgent removeOfAgent(NetworkId networkId) {
        Versioned<OFAgent> ofAgent = ofAgentStore.remove(networkId);
        return ofAgent == null ? null : ofAgent.value();
    }

    @Override
    public OFAgent ofAgent(NetworkId networkId) {
        Versioned<OFAgent> ofAgent = ofAgentStore.get(networkId);
        return ofAgent == null ? null : ofAgent.value();
    }

    @Override
    public Set<OFAgent> ofAgents() {
        Set<OFAgent> ofAgents = ofAgentStore.values().stream()
                .map(Versioned::value)
                .collect(Collectors.toSet());
        return ImmutableSet.copyOf(ofAgents);
    }

    private class OFAgentMapListener implements MapEventListener<NetworkId, OFAgent> {

        @Override
        public void event(MapEvent<NetworkId, OFAgent> event) {
            switch (event.type()) {
                case INSERT:
                    eventExecutor.execute(() -> {
                        log.debug(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + event.newValue().value().tenantId()
                                          + " OFAgent for network {} created", event.key());
                        notifyDelegate(new OFAgentEvent(
                                Type.OFAGENT_CREATED,
                                event.newValue().value()));
                    });
                    break;
                case UPDATE:
                    eventExecutor.execute(() -> {
                        log.debug(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + event.newValue().value().tenantId()
                                          + " OFAgent for network {} updated", event.key());
                        processUpdated(event.oldValue().value(), event.newValue().value());
                    });
                    break;
                case REMOVE:
                    eventExecutor.execute(() -> {
                        log.debug(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + event.oldValue().value().tenantId()
                                          + " OFAgent for network {} removed", event.key());
                        notifyDelegate(new OFAgentEvent(
                                Type.OFAGENT_REMOVED,
                                event.oldValue().value()));
                    });
                    break;
                default:
                    break;
            }
        }

        private void processUpdated(OFAgent oldValue, OFAgent newValue) {
            if (!oldValue.controllers().equals(newValue.controllers())) {
                oldValue.controllers().stream()
                        .filter(controller -> !newValue.controllers().contains(controller))
                        .forEach(controller -> notifyDelegate(new OFAgentEvent(
                                OFAGENT_CONTROLLER_REMOVED,
                                newValue,
                                controller)
                        ));

                newValue.controllers().stream()
                        .filter(controller -> !oldValue.controllers().contains(controller))
                        .forEach(controller -> notifyDelegate(new OFAgentEvent(
                                OFAGENT_CONTROLLER_ADDED,
                                newValue,
                                controller
                        )));
            }

            if (oldValue.state() != newValue.state()) {
                Type eventType = newValue.state() == STARTED ? OFAGENT_STARTED : OFAGENT_STOPPED;
                notifyDelegate(new OFAgentEvent(eventType, newValue));
            }
        }
    }
}
