/*
 * Copyright 2016-present 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.driver.optical.handshaker;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.onosproject.net.Device;
import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
import org.projectfloodlight.openflow.protocol.OFCalientFlowStatsRequest;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsRequest;
import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFObject;
import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
import org.projectfloodlight.openflow.protocol.OFStatsRequest;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Driver for Calient S160 Optical Circuit Switch. Untested on Calient S320 but probably works ok.
 *
 * Driver implements custom handshaker, and rewrites flow stats as expected by the device. Port stats are currently
 * not supported.
 *
 * The device consists of OMS ports only.
 */
public class CalientFiberSwitchHandshaker extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {

    private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
    private List<OFCalientPortDescStatsEntry> fiberPorts = new ArrayList<>();


    @Override
    public Boolean supportNxRole() {
        return false;
    }

    @Override
    public void startDriverHandshake() {
        log.warn("Starting driver handshake for sw {}", getStringId());
        if (startDriverHandshakeCalled) {
            throw new SwitchDriverSubHandshakeAlreadyStarted();
        }
        startDriverHandshakeCalled = true;
        try {
            sendHandshakeOFExperimenterPortDescRequest();
        } catch (IOException e) {
            log.error("Exception while sending experimenter port desc:", e);
        }

    }

    private void sendHandshakeOFExperimenterPortDescRequest() throws IOException {
        // send multi part message for port description for optical switches
        OFCalientPortDescStatsRequest portsRequest = factory()
                .buildCalientPortDescStatsRequest()
                .build();
        log.warn("Sending experimenter port description message {}",
                portsRequest.toString());
        this.sendHandshakeMessage(portsRequest);
    }

    @Override
    public boolean isDriverHandshakeComplete() {
        return driverHandshakeComplete.get();
    }

    @Override
    public void processDriverHandshakeMessage(OFMessage m) {
        if (!startDriverHandshakeCalled) {
            throw new SwitchDriverSubHandshakeNotStarted();
        }
        if (driverHandshakeComplete.get()) {
            throw new SwitchDriverSubHandshakeCompleted(m);
        }

        switch (m.getType()) {
            case BARRIER_REPLY:
                break;
            case ERROR:
                log.error("Switch Error {} {}", getStringId(), m);
                break;
            case FEATURES_REPLY:
                break;
            case FLOW_REMOVED:
                break;
            case GET_ASYNC_REPLY:
                break;
            case PACKET_IN:
                break;
            case PORT_STATUS:
                break;
            case QUEUE_GET_CONFIG_REPLY:
                break;
            case ROLE_REPLY:
                break;
            case STATS_REPLY:
                log.warn("Received port desc reply");
                OFCalientPortDescStatsReply descStatsReply = (OFCalientPortDescStatsReply) m;
                fiberPorts.addAll(descStatsReply.getPortDesc());
                // Multi-part message
                if (!descStatsReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
                    driverHandshakeComplete.set(true);
                }
                break;
            default:
                log.warn("Received message {} during switch-driver " +
                                "subhandshake " + "from switch {} ... " +
                                "Ignoring message", m,
                        getStringId());

        }
    }

    @Override
    public Device.Type deviceType() {
        return Device.Type.FIBER_SWITCH;
    }

    @Override
    public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
        return ImmutableList.copyOf(fiberPorts);
    }

    @Override
    public Set<PortDescPropertyType> getPortTypes() {
        return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
    }

    @Override
    public final void sendMsg(OFMessage m) {
        OFMessage newMsg = m;

        if (m.getType() == OFType.STATS_REQUEST) {
            OFStatsRequest sr = (OFStatsRequest) m;
            log.debug("Rebuilding stats request type {}", sr.getStatsType());
            switch (sr.getStatsType()) {
                case FLOW:
                    OFCalientFlowStatsRequest request = this.factory().buildCalientFlowStatsRequest()
                            .setCookie(((OFFlowStatsRequest) sr).getCookie())
                            .setCookieMask(((OFFlowStatsRequest) sr).getCookieMask())
                            .setMatch(this.factory().matchWildcardAll())
                            .setOutGroup(((OFFlowStatsRequest) sr).getOutGroup().getGroupNumber())
                            .setOutPort(OFPort.ANY)
                            .setTableId(TableId.ALL)
                            .setXid(sr.getXid())
                            .setFlags(sr.getFlags())
                            .build();
                    newMsg = request;
                    break;
                case PORT:
                    // TODO
                    break;
                default:
                    break;
            }
        }

        super.sendMsg(newMsg);
    }
}
