/*
 * 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 com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.Map;
import java.util.Optional;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onosproject.net.Device;
import org.onosproject.net.Port;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractBehaviour;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.optical.OchPort;
import org.onosproject.net.optical.OduCltPort;
import org.onosproject.net.optical.OmsPort;
import org.onosproject.net.optical.OpticalDevice;
import org.onosproject.net.optical.device.port.OchPortMapper;
import org.onosproject.net.optical.device.port.OduCltPortMapper;
import org.onosproject.net.optical.device.port.OmsPortMapper;
import org.onosproject.net.optical.device.port.PortMapper;
import org.onosproject.net.optical.utils.ForwardingDevice;
import org.slf4j.Logger;

import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;

// FIXME This needs to be moved back to org.onosproject.net.optical.impl
// after optical driver package separation process is complete.
/**
 * Implementation of {@link OpticalDevice}.
 * <p>
 * Currently supports
 * <ul>
 *  <li> {@link OchPort}
 * </ul>
 */
@Beta
public class DefaultOpticalDevice
        extends AbstractBehaviour
        implements OpticalDevice, ForwardingDevice {

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

    // shared Port type handler map.
    // TODO Is there a use case, where we need to differentiate this map per Device?
    private static final Map<Class<? extends Port>, PortMapper<? extends Port>> MAPPERS
        = ImmutableMap.<Class<? extends Port>, PortMapper<? extends Port>>builder()
            .put(OchPort.class, new OchPortMapper())
            .put(OmsPort.class, new OmsPortMapper())
            .put(OduCltPort.class, new OduCltPortMapper())
            // TODO add other optical port type here
            .build();



    // effectively final
    private Device delegate;

    // Default constructor required as a Behaviour.
    public DefaultOpticalDevice() {}

    @Override
    public Device delegate() {
        if (delegate == null) {
            // dirty work around.
            // wanted to pass delegate Device at construction,
            // but was not possible. A Behaviour requires no-arg constructor.
            checkState(data() != null, "DriverData must exist");
            DriverData data = data();
            DeviceService service = DefaultServiceDirectory.getService(DeviceService.class);
            delegate = checkNotNull(service.getDevice(data.deviceId()),
                                    "No Device found for %s", data.deviceId());
        }
        return delegate;
    }

    @Override
    public <T extends Port> boolean portIs(Port port, Class<T> portClass) {

        PortMapper<? extends Port> mapper = MAPPERS.get(portClass);
        if (mapper != null) {
            return mapper.is(port);
        }
        return false;
    }

    @Override
    public <T extends Port> Optional<T> portAs(Port port, Class<T> portClass) {
        PortMapper<? extends Port> mapper = MAPPERS.get(portClass);
        if (mapper != null) {
            return (Optional<T>) (mapper.as(port));
        }
        return Optional.empty();
    }

    @Override
    public Port port(Port port) {
        for (PortMapper<? extends Port> mapper : MAPPERS.values()) {
            if (mapper.is(port)) {
                return mapper.as(port).map(Port.class::cast).orElse(port);
            }
        }
        return port;
    }

    @Override
    public boolean equals(Object obj) {
        return delegate().equals(obj);
    }

    @Override
    public int hashCode() {
        return delegate().hashCode();
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("delegate", delegate)
                .toString();
    }
}
