/*
 * 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.mapping.impl;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import org.onosproject.mapping.DefaultMapping;
import org.onosproject.mapping.DefaultMappingEntry;
import org.onosproject.mapping.Mapping;
import org.onosproject.mapping.MappingEntry;
import org.onosproject.mapping.MappingEvent;
import org.onosproject.mapping.MappingId;
import org.onosproject.mapping.MappingKey;
import org.onosproject.mapping.MappingStore;
import org.onosproject.mapping.MappingStoreDelegate;
import org.onosproject.mapping.MappingTreatment;
import org.onosproject.mapping.MappingValue;
import org.onosproject.mapping.actions.MappingAction;
import org.onosproject.mapping.addresses.MappingAddress;
import org.onosproject.mapping.instructions.MappingInstruction;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
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.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.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of a distributed store for managing mapping information.
 */
@Component(immediate = true, service = MappingStore.class)
public class DistributedMappingStore
        extends AbstractStore<MappingEvent, MappingStoreDelegate>
        implements MappingStore {

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

    private ConsistentMap<MappingId, Mapping> database;
    private ConsistentMap<MappingId, Mapping> cache;

    private Map<MappingId, Mapping> databaseMap;
    private Map<MappingId, Mapping> cacheMap;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DeviceService deviceService;

    private final MapEventListener<MappingId, Mapping> listener = new InternalListener();

    @Activate
    public void activate() {

        Serializer serializer = Serializer.using(KryoNamespaces.API,
                                                    Mapping.class,
                                                    DefaultMapping.class,
                                                    MappingId.class,
                                                    MappingEvent.Type.class,
                                                    MappingKey.class,
                                                    MappingValue.class,
                                                    MappingAddress.class,
                                                    MappingAddress.Type.class,
                                                    MappingAction.class,
                                                    MappingAction.Type.class,
                                                    MappingTreatment.class,
                                                    MappingInstruction.class,
                                                    MappingInstruction.Type.class);

        database = storageService.<MappingId, Mapping>consistentMapBuilder()
                        .withName("onos-mapping-database")
                        .withSerializer(serializer)
                        .build();

        cache = storageService.<MappingId, Mapping>consistentMapBuilder()
                        .withName("onos-mapping-cache")
                        .withSerializer(serializer)
                        .build();

        database.addListener(listener);
        cache.addListener(listener);
        databaseMap = database.asJavaMap();
        cacheMap = cache.asJavaMap();
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        database.removeListener(listener);
        cache.removeListener(listener);
        log.info("Stopped");
    }

    /**
     * Obtains map representation of mapping store.
     *
     * @param type mapping store type
     * @return map representation of mapping store
     */
    private Map<MappingId, Mapping> getStoreMap(Type type) {
        switch (type) {
            case MAP_DATABASE:
                return databaseMap;
            case MAP_CACHE:
                return cacheMap;
            default:
                log.warn("Unrecognized map store type {}", type);
                return Maps.newConcurrentMap();
        }
    }

    /**
     * Obtains mapping store.
     *
     * @param type mapping store type
     * @return mapping store
     */
    private ConsistentMap<MappingId, Mapping> getStore(Type type) {
        switch (type) {
            case MAP_DATABASE:
                return database;
            case MAP_CACHE:
                return cache;
            default:
                throw new IllegalArgumentException("Wrong mapping store " + type);
        }
    }

    @Override
    public int getMappingCount(Type type) {
        AtomicInteger sum = new AtomicInteger(0);
        deviceService.getDevices().forEach(device ->
                sum.addAndGet(Iterables.size(getMappingEntries(type, device.id()))));
        return sum.get();
    }

    @Override
    public Iterable<MappingEntry> getAllMappingEntries(Type type) {

        Map<MappingId, Mapping> storeMap = getStoreMap(type);
        return ImmutableList.copyOf(storeMap.values().stream()
                                            .map(DefaultMappingEntry::new)
                                            .collect(Collectors.toList()));
    }

    @Override
    public MappingEntry getMappingEntry(Type type, Mapping mapping) {

        return new DefaultMappingEntry(getStoreMap(type).get(mapping.id()));
    }

    @Override
    public Iterable<MappingEntry> getMappingEntries(Type type, DeviceId deviceId) {

        Map<MappingId, Mapping> storeMap = getStoreMap(type);
        return ImmutableList.copyOf(storeMap.values().stream()
                                             .filter(m -> m.deviceId() == deviceId)
                                             .map(DefaultMappingEntry::new)
                                             .collect(Collectors.toList()));
    }

    @Override
    public void storeMapping(Type type, MappingEntry mapping) {

        getStore(type).put(mapping.id(), mapping);
    }

    @Override
    public MappingEvent removeMapping(Type type, Mapping mapping) {

        getStore(type).remove(mapping.id());
        return null;
    }

    @Override
    public void pendingDeleteMapping(Type type, Mapping mapping) {
        // TODO: this will be implemented when management plane is ready
        log.error("This method will be available when management plane is ready");
    }

    @Override
    public MappingEvent addOrUpdateMappingEntry(Type type, MappingEntry entry) {
        // TODO: this will be implemented when management plane is ready
        log.error("This method will be available when management plane is ready");
        return null;
    }

    @Override
    public MappingEvent pendingMappingEntry(Type type, MappingEntry entry) {
        // TODO: this will be implemented when management plane is ready
        log.error("This method will be available when management plane is ready");
        return null;
    }

    @Override
    public void purgeMappingEntries(Type type) {
        getStore(type).clear();
    }

    /**
     * Event listener to notify delegates about mapping events.
     */
    private class InternalListener implements MapEventListener<MappingId, Mapping> {

        @Override
        public void event(MapEvent<MappingId, Mapping> event) {
            final MappingEvent.Type type;
            final Mapping mapping;

            switch (event.type()) {
                case INSERT:
                    type = MappingEvent.Type.MAPPING_ADDED;
                    mapping = event.newValue().value();
                    break;
                case UPDATE:
                    type = MappingEvent.Type.MAPPING_UPDATED;
                    mapping = event.newValue().value();
                    break;
                case REMOVE:
                    type = MappingEvent.Type.MAPPING_REMOVED;
                    mapping = event.oldValue().value();
                    break;
                default:
                    throw new IllegalArgumentException("Wrong event type " + event.type());
            }
            notifyDelegate(new MappingEvent(type, mapping));
        }
    }
}
