/*
 * 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.optical.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));
        }
    }

}
