/*
 * Copyright 2020-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.k8snode.impl;

import com.google.common.collect.ImmutableSet;
import org.onlab.packet.IpAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.k8snode.api.DefaultK8sHost;
import org.onosproject.k8snode.api.K8sHost;
import org.onosproject.k8snode.api.K8sHostEvent;
import org.onosproject.k8snode.api.K8sHostState;
import org.onosproject.k8snode.api.K8sHostStore;
import org.onosproject.k8snode.api.K8sHostStoreDelegate;
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.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;

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.k8snode.api.K8sHostEvent.Type.K8S_HOST_COMPLETE;
import static org.onosproject.k8snode.api.K8sHostEvent.Type.K8S_HOST_CREATED;
import static org.onosproject.k8snode.api.K8sHostEvent.Type.K8S_HOST_INCOMPLETE;
import static org.onosproject.k8snode.api.K8sHostEvent.Type.K8S_HOST_REMOVED;
import static org.onosproject.k8snode.api.K8sHostEvent.Type.K8S_HOST_UPDATED;
import static org.onosproject.k8snode.api.K8sHostEvent.Type.K8S_NODES_ADDED;
import static org.onosproject.k8snode.api.K8sHostEvent.Type.K8S_NODES_REMOVED;
import static org.onosproject.k8snode.api.K8sHostState.COMPLETE;
import static org.onosproject.k8snode.api.K8sHostState.INCOMPLETE;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of kubernetes host store using consistent map.
 */
@Component(immediate = true, service = K8sHostStore.class)
public class DistributedK8sHostStore
        extends AbstractStore<K8sHostEvent, K8sHostStoreDelegate>
        implements K8sHostStore {

    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 String APP_ID = "org.onosproject.k8snode";

    private static final KryoNamespace
            SERIALIZER_K8S_HOST = KryoNamespace.newBuilder()
            .register(KryoNamespaces.API)
            .register(K8sHost.class)
            .register(DefaultK8sHost.class)
            .register(K8sHostState.class)
            .register(Collection.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<String, K8sHost> hostMapListener =
            new K8sHostMapListener();
    private ConsistentMap<String, K8sHost> hostStore;

    @Activate
    protected void activate() {
        ApplicationId appId = coreService.registerApplication(APP_ID);
        hostStore = storageService.<String, K8sHost>consistentMapBuilder()
                .withSerializer(Serializer.using(SERIALIZER_K8S_HOST))
                .withName("k8s-hoststore")
                .withApplicationId(appId)
                .build();
        hostStore.addListener(hostMapListener);
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        hostStore.removeListener(hostMapListener);
        eventExecutor.shutdown();
        log.info("Stopped");
    }

    @Override
    public void createHost(K8sHost host) {
        hostStore.compute(host.hostIp().toString(), (hostIp, existing) -> {
            final String error = host.hostIp().toString() + ERR_DUPLICATE;
            checkArgument(existing == null, error);
            return host;
        });
    }

    @Override
    public void updateHost(K8sHost host) {
        hostStore.compute(host.hostIp().toString(), (hostIp, existing) -> {
            final String error = host.hostIp().toString() + ERR_NOT_FOUND;
            checkArgument(existing != null, error);
            return host;
        });
    }

    @Override
    public K8sHost removeHost(IpAddress hostIp) {
        Versioned<K8sHost> host = hostStore.remove(hostIp.toString());
        if (host == null) {
            final String error = hostIp.toString() + ERR_NOT_FOUND;
            throw new IllegalArgumentException(error);
        }
        return host.value();
    }

    @Override
    public Set<K8sHost> hosts() {
        return ImmutableSet.copyOf(hostStore.asJavaMap().values());
    }

    @Override
    public K8sHost host(IpAddress hostIp) {
        return hostStore.asJavaMap().get(hostIp.toString());
    }

    private class K8sHostMapListener
            implements MapEventListener<String, K8sHost> {

        @Override
        public void event(MapEvent<String, K8sHost> event) {
            switch (event.type()) {
                case INSERT:
                    log.debug("Kubernetes host created {}", event.newValue());
                    eventExecutor.execute(() ->
                            notifyDelegate(new K8sHostEvent(
                                    K8S_HOST_CREATED, event.newValue().value()
                            )));
                    break;
                case UPDATE:
                    log.debug("Kubernetes host updated {}", event.newValue());
                    eventExecutor.execute(() -> {
                        notifyDelegate(new K8sHostEvent(
                                K8S_HOST_UPDATED, event.newValue().value()
                        ));

                        if (event.newValue().value().state() == COMPLETE) {
                            notifyDelegate(new K8sHostEvent(
                                    K8S_HOST_COMPLETE,
                                    event.newValue().value()
                            ));
                        } else if (event.newValue().value().state() == INCOMPLETE) {
                            notifyDelegate(new K8sHostEvent(
                                    K8S_HOST_INCOMPLETE,
                                    event.newValue().value()
                            ));
                        }

                        K8sHost origHost = event.newValue().value();
                        Set<String> oldNodes = event.oldValue().value().nodeNames();
                        Set<String> newNodes = event.newValue().value().nodeNames();

                        Set<String> addedNodes = new HashSet<>(newNodes);
                        Set<String> removedNodes = new HashSet<>(oldNodes);

                        addedNodes.removeAll(oldNodes);
                        removedNodes.removeAll(newNodes);

                        if (addedNodes.size() > 0) {
                            K8sHost addedHost = DefaultK8sHost.builder()
                                    .hostIp(origHost.hostIp())
                                    .state(origHost.state())
                                    .nodeNames(addedNodes)
                                    .build();
                            notifyDelegate(new K8sHostEvent(K8S_NODES_ADDED, addedHost));
                        }

                        if (removedNodes.size() > 0) {
                            K8sHost removedHost = DefaultK8sHost.builder()
                                    .hostIp(origHost.hostIp())
                                    .state(origHost.state())
                                    .nodeNames(removedNodes)
                                    .build();
                            notifyDelegate(new K8sHostEvent(K8S_NODES_REMOVED, removedHost));
                        }
                    });
                    break;
                case REMOVE:
                    log.debug("Kubernetes host removed {}", event.oldValue());
                    eventExecutor.execute(() ->
                            notifyDelegate(new K8sHostEvent(
                                    K8S_HOST_REMOVED, event.oldValue().value()
                            )));
                    break;
                default:
                    // do nothing
                    break;
            }
        }
    }
}
