/*
 * 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.dhcprelay.store;

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.apache.felix.scr.annotations.Property;
import org.onlab.util.KryoNamespace;
import org.onosproject.store.StoreDelegate;
import org.onlab.packet.IpPrefix;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapEvent;
import org.onosproject.store.service.EventuallyConsistentMapListener;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.routing.fpm.api.FpmRecord;
import org.onosproject.routing.fpm.api.FpmPrefixStoreEvent;




import org.slf4j.Logger;

import java.util.Collection;
import java.util.Optional;




import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Persistent Fpm Prefix Store with Listener.
 */
@Component(immediate = true)
@Property(name = "fpm_type", value = "DHCP")
@Service
public class DistributedFpmPrefixStore implements DhcpFpmPrefixStore {

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

    private Logger log = getLogger(getClass());
    private StoreDelegate<FpmPrefixStoreEvent> delegate;
    private EventuallyConsistentMap<IpPrefix, FpmRecord> dhcpFpmRecords;
    private EventuallyConsistentMapListener<IpPrefix, FpmRecord> listener;

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

    @Activate
    protected void activated() {
        dhcpFpmRecords = storageService.<IpPrefix, FpmRecord>eventuallyConsistentMapBuilder()
                .withName("DHCP-FPM-Records")
                .withTimestampProvider((k, v) -> new WallClockTimestamp())
                .withSerializer(APP_KRYO)
                .withPersistence()
                .build();
        listener = new InternalMapListener();
        dhcpFpmRecords.addListener(listener);
    }

    @Deactivate
    protected void deactivated() {
        dhcpFpmRecords.removeListener(listener);
        dhcpFpmRecords.destroy().join();
    }

    @Override
    public void setDelegate(StoreDelegate<FpmPrefixStoreEvent> delegate) {
        checkNotNull("Delegate can't be null", delegate);
        this.delegate = delegate;
    }

    @Override
    public void unsetDelegate(StoreDelegate<FpmPrefixStoreEvent> delegate) {
        this.delegate = null;
    }

    @Override
    public boolean hasDelegate() {
        return delegate != null;
    }

    @Override
    public Optional<FpmRecord> getFpmRecord(IpPrefix prefix) {
        checkNotNull(prefix, "Prefix can't be null");
        return Optional.ofNullable(dhcpFpmRecords.get(prefix));
    }

    @Override
    public Collection<FpmRecord> getFpmRecords() {
        return dhcpFpmRecords.values();
    }

    /**
     * Add a dhcp fpm entry.
     *
     * @param prefix the route prefix in the advertisement
     * @param fpmRecord the route for fpm
     **/
    public void addFpmRecord(IpPrefix prefix, FpmRecord fpmRecord) {
        checkNotNull(prefix, "Prefix can't be null");
        checkNotNull(fpmRecord, "Fpm record can't be null");
        dhcpFpmRecords.put(prefix, fpmRecord);
    }

    /**
     * Remove a dhcp fpm entry.
     *
     * @param prefix the route prefix in the advertisement
     * @return none
     **/
    public Optional<FpmRecord> removeFpmRecord(IpPrefix prefix) {
        checkNotNull(prefix, "Prefix can't be null");
        return Optional.ofNullable(dhcpFpmRecords.remove(prefix));
    }

    /**
     * Internal map listener for Fpm records map.
     */
    private class InternalMapListener implements EventuallyConsistentMapListener<IpPrefix, FpmRecord> {
        @Override
        public void event(EventuallyConsistentMapEvent<IpPrefix, FpmRecord> event) {
            FpmPrefixStoreEvent.Type eventType;
            switch (event.type()) {
                case PUT:
                    eventType = FpmPrefixStoreEvent.Type.ADD;
                    break;
                case REMOVE:
                    eventType = FpmPrefixStoreEvent.Type.REMOVE;
                    break;
                default:
                    log.warn("Unknown event type {}", event.type());
                    return;
            }
            if (delegate != null) {
                delegate.notify(new FpmPrefixStoreEvent(eventType, event.value()));
            }
        }
    }
}
