/*
 * Copyright 2016 Open Networking Laboratory
 *
 * 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.net.optical.device;

import static org.slf4j.LoggerFactory.getLogger;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.optical.OpticalDevice;
import org.onosproject.net.utils.ForwardingDeviceService;
import org.slf4j.Logger;

import com.google.common.annotations.Beta;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.commons.lang3.tuple.Pair;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Element;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;


// TODO replace places using DeviceService expecting Optical specific ports.
// with this

/**
 * Decorator, which provides a DeviceService view, which returns
 * Ports in optical specific ports.
 */
@Beta
public class OpticalDeviceServiceView
    extends ForwardingDeviceService
    implements DeviceService {

    private static final Logger log = getLogger(OpticalDeviceServiceView.class);

    /**
     * DeviceListener to wrapped DeviceListener map.
     * <p>
     * {@literal original listener -> wrapped listener}
     */
    private final Map<DeviceListener, DeviceListener> wrapped = Maps.newIdentityHashMap();

    // May need a way to monitor Drivers loaded on ONOS and
    // invalidate this Cache if a driver was added/updated
    /**
     * Device to {@link OpticalDevice} map cache.
     */
    private final LoadingCache<Element, Optional<OpticalDevice>> optdev
        = CacheBuilder.newBuilder()
            .weakKeys() // == for Key comparison
            .maximumSize(100)
            .build(CacheLoader.from(elm -> {
                if (elm.is(OpticalDevice.class)) {
                    return Optional.of(elm.as(OpticalDevice.class));
                } else {
                    return Optional.empty();
                }
            }));

    // Not intended to be instantiated directly
    protected OpticalDeviceServiceView(DeviceService base) {
        super(base);
    }

    /**
     * Wraps the given DeviceService to provide a view,
     * which returns port as optical specific Port class.
     *
     * @param base {@link DeviceService} view to use as baseline.
     * @return Decorated view of {@code base}
     */
    public static OpticalDeviceServiceView opticalView(DeviceService base) {
        // TODO might make sense to track and assign an instance for each `base`
        return new OpticalDeviceServiceView(base);
    }

    /**
     * Transform Port instance on the event to Optical specific port, if it is well-formed.
     *
     * @param event original event to transform
     * @return transformed {@link DeviceEvent}
     */
    public DeviceEvent augment(DeviceEvent event) {
        final Port port = augment(event.port());
        if (port == event.port()) {
            // If the Port not changed, pass through
            return event;
        }
        return new DeviceEvent(event.type(), event.subject(), port, event.time());
    }

    /**
     * Transform Port instance to Optical specific port, if it is well-formed.
     *
     * @param port Port instance to translate
     * @return Optical specific port instance or original {@code port}.
     */
    public Port augment(Port port) {
        if (port == null) {
            return null;
        }
        return optdev.getUnchecked(port.element())
            .map(odev -> odev.port(port))
            .orElse(port);
    }

    @Override
    public void addListener(DeviceListener listener) {
        super.addListener(wrapped.computeIfAbsent(listener, OpticalDeviceListener::new));
    }

    @Override
    public void removeListener(DeviceListener listener) {
        DeviceListener wrappedListener = wrapped.remove(listener);
        if (wrappedListener != null) {
            super.removeListener(wrappedListener);
        }
    }


    @Override
    public List<Port> getPorts(DeviceId deviceId) {
        return Lists.transform(super.getPorts(deviceId),
                               this::augment);
    }

    @Override
    public Port getPort(DeviceId deviceId, PortNumber portNumber) {
        return augment(super.getPort(deviceId, portNumber));
    }


    /**
     * DeviceListener, which translates generic Port to optical specific Port
     * before passing.
     */
    class OpticalDeviceListener implements DeviceListener {

        private final DeviceListener listener;

        // shallow cache to reuse transformed event in isRelevant and event call
        private Pair<DeviceEvent, DeviceEvent> cache;

        public OpticalDeviceListener(DeviceListener listener) {
            this.listener = listener;
        }

        private DeviceEvent opticalEvent(DeviceEvent event) {

            Pair<DeviceEvent, DeviceEvent> entry = cache;
            if (entry != null && entry.getLeft() == event) {
                return entry.getRight();
            }

            DeviceEvent opticalEvent = augment(event);
            cache = Pair.of(event, opticalEvent);
            return opticalEvent;
        }

        @Override
        public boolean isRelevant(DeviceEvent event) {
            return listener.isRelevant(opticalEvent(event));
        }

        @Override
        public void event(DeviceEvent event) {
            listener.event(opticalEvent(event));
        }
    }

}
