/*
 * 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.drivers.lumentum;

import com.google.common.collect.ImmutableList;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.lang3.tuple.Pair;
import org.onlab.util.Frequency;
import org.onlab.util.Spectrum;
import org.onosproject.drivers.odtn.impl.DeviceConnectionCache;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.PortNumber;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OchSignalType;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.GridType;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.flow.DefaultFlowEntry;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleProgrammable;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Implementation of FlowRuleProgrammable interface for Lumentum ROADM-A Whitebox devices using NETCONF.
 */
public class LumentumNetconfRoadmFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {

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

    private static final String DN = "dn";
    private static final String DN_PORT = "port=";
    private static final String DN_CARD1 = "ne=1;chassis=1;card=1;port=";
    private static final String CONNECTION = "connection";
    private static final String CONNECTIONS = "data.connections.connection";
    private static final String CONFIG = "config";
    private static final String STATE = "state";
    private static final String START_FREQ = "start-freq";
    private static final String END_FREQ = "end-freq";
    private static final String MODULE = "module";
    private static final String SEMI_COLON = ";";
    private static final String EQUAL = "=";
    private static final String INPUT_PORT_REFERENCE = "input-port-reference";
    private static final String OUTPUT_PORT_REFERENCE = "output-port-reference";

    private static final String CHANNEL_ATTENUATION = "attenuation";
    private static final String CHANNEL_INPUT_POWER = "input-channel-attributes.power";
    private static final String CHANNEL_OUTPUT_POWER = "output-channel-attributes.power";

    protected static final long LINE_PORT = 3001;
    protected static final PortNumber LINE_PORT_NUMBER = PortNumber.portNumber(LINE_PORT);
    protected static final long MUX_OUT = 4201;
    protected static final long DEMUX_IN = 5101;
    protected static final long GHZ = 1_000_000_000L;
    protected static final int LUMENTUM_ROADM20_MAX_CONNECTIONS = 100;

    /**Get the flow entries that are present on the Lumentum device, called by FlowRuleDriverProvider.
     *
     * The flow entries must match exactly the FlowRule entries in the ONOS store. If they are not an
     * exact match the device will be requested to remove those flows.
     *
     * @return A collection of Flow Entries
     */
    @Override
    public Collection<FlowEntry> getFlowEntries() {
        Collection<FlowEntry> fetched = fetchConnectionsFromDevice().stream()
                .map(conn -> buildFlowrule(conn))
                .map(fr -> new DefaultFlowEntry(fr, FlowEntry.FlowEntryState.ADDED, 0, 0, 0))
                .collect(Collectors.toList());

        //Print out number of rules actually found on the device that are also included in the cache
        log.debug("Device {} getFlowEntries fetched connections {}", did(), fetched.size());

        return fetched;
    }

    /**Apply the flow entries specified in the collection rules.
     *
     * @param rules A collection of Flow Rules to be applied to the Lumentum device
     * @return The collection of added Flow Entries
     */
    @Override
    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
        //Check NETCONF session
        NetconfSession session = getNetconfSession();
        if (session == null) {
            log.error("Device {} null session", did());
            return ImmutableList.of();
        }

        // Apply the  rules on the device and add to cache if success
        Collection<FlowRule> added = new ArrayList<>();
        for (FlowRule flowRule : rules) {
            LumentumFlowRule lumFlowRule = new LumentumFlowRule(flowRule, getLinePorts());

            if (rpcAddConnection(lumFlowRule)) {
                added.add(lumFlowRule);
                getConnectionCache().add(did(), lumFlowRule.getConnectionName(), lumFlowRule);
                log.debug("Adding connection with selector {}", lumFlowRule.selector());
            }
        }

        //Print out number of rules sent to the device (without receiving errors)
        log.debug("Device {} applyFlowRules added {}", did(), added.size());

        return added;
    }

    @Override
    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
        NetconfSession session = getNetconfSession();
        if (session == null) {
            log.error("Device {} null session", did());
            return ImmutableList.of();
        }

        // Remove the rules from the device and from the cache
        List<FlowRule> removed = new ArrayList<>();
        for (FlowRule r : rules) {
            try {
                LumentumFlowRule flowRule = new LumentumFlowRule(r, getLinePorts());
                rpcDeleteConnection(flowRule);
                getConnectionCache().remove(did(), r);
                removed.add(r);
            } catch (Exception e) {
                log.error("Device {} Error {}", did(), e);
                continue;
            }
        }

        //Print out number of removed rules from the device (without receiving errors)
        log.debug("Device {} removeFlowRules removed {}", did(), removed.size());

        return removed;
    }

    private List<PortNumber> getLinePorts() {
        DeviceService deviceService = this.handler().get(DeviceService.class);
        return deviceService.getPorts(data().deviceId()).stream()
                .filter(p -> p.number().toLong() == LINE_PORT)
                .map(p -> p.number())
                .collect(Collectors.toList());
    }

    /**
     * Fetches list of connections from device.
     *
     * @return list of connections as XML hierarchy
     */
    private List<HierarchicalConfiguration> fetchConnectionsFromDevice() {
        String reply;

        StringBuilder requestBuilder = new StringBuilder();
        requestBuilder.append("<connections xmlns=\"http://www.lumentum.com/lumentum-ote-connection\">");
        requestBuilder.append("</connections>");

        NetconfSession session = getNetconfSession();
        if (session == null) {
            log.error("Lumentum NETCONF - session not found for {}", handler().data().deviceId());
            return ImmutableList.of();
        }

        try {
            reply = session.get(requestBuilder.toString(), null);
            log.debug("Lumentum NETCONF - fetchConnectionsFromDevice reply {}", reply);
        } catch (NetconfException e) {
            log.error("Failed to retrieve configuration details for device {}",
                      handler().data().deviceId(), e);
            return ImmutableList.of();
        }

        HierarchicalConfiguration cfg =
                XmlConfigParser.loadXml(new ByteArrayInputStream(reply.getBytes()));

        return cfg.configurationsAt(CONNECTIONS);
    }

    // Example input dn: ne=1;chassis=1;card=1;module=2;connection=89
    private Pair<Short, Short> parseDn(String dn) {
        Short module = null;
        Short connection = null;
        for (String entry : dn.split(SEMI_COLON)) {
            String[] keyVal = entry.split(EQUAL);
            if (keyVal.length != 2) {
                continue;
            }
            if (keyVal[0].equals(MODULE)) {
                module = Short.valueOf(keyVal[1]);
            }
            if (keyVal[0].equals(CONNECTION)) {
                connection = Short.valueOf(keyVal[1]);
            }
            if (module != null && connection != null) {
                return Pair.of(module, connection);
            }
        }

        return null;
    }

    /**
     * Builds a flow rule from a connection hierarchy.
     *
     * @param connection the connection hierarchy
     * @return the flow rule
     */
    private FlowRule buildFlowrule(HierarchicalConfiguration connection) {

        String dn = connection.getString(DN);
        Pair<Short, Short> pair = parseDn(dn);
        short connId = pair.getRight();
        short moduleId = pair.getLeft();

        if (pair == null) {
            log.error("Lumentum NETCONF - device {} error in retrieving DN field", did());
            return null;
        }

        log.debug("Lumentum NETCONF - retrieved FlowRule module {} connection {}", moduleId, connId);

        HierarchicalConfiguration config = connection.configurationAt(CONFIG);
        double startFreq = config.getDouble(START_FREQ);
        double endFreq = config.getDouble(END_FREQ);
        String inputPortReference = config.getString(INPUT_PORT_REFERENCE);
        String outputPortReference = config.getString(OUTPUT_PORT_REFERENCE);

        HierarchicalConfiguration state = connection.configurationAt(STATE);
        double attenuation = state.getDouble(CHANNEL_ATTENUATION);
        double inputPower = state.getDouble(CHANNEL_INPUT_POWER);
        double outputPower = state.getDouble(CHANNEL_OUTPUT_POWER);

        PortNumber portNumber = getPortNumber(moduleId, inputPortReference, outputPortReference);

        //If rule is on module 1 it means input port in the Flow rule is contained in portNumber.
        //Otherwise the input port in the Flow rule must is the line port.
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchInPort(moduleId == 1 ? portNumber : LINE_PORT_NUMBER)
                .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
                .add(Criteria.matchLambda(toOchSignal(startFreq, endFreq)))
                .build();

        log.debug("Lumentum NETCONF - retrieved FlowRule startFreq {} endFreq {}", startFreq, endFreq);
        log.debug("Lumentum NETCONF - retrieved FlowRule selector {}", selector);

        //Lookup of connection
        //Retrieved rules, cached rules are considered equal if the selector is equal
        FlowRule cacheRule = null;
        if (getConnectionCache().size(did()) != 0) {
            cacheRule = getConnectionCache().get(did()).stream()
                    .filter(r -> (r.selector().equals(selector)))
                    .findFirst()
                    .orElse(null);
        }


        if (cacheRule == null) {
            //TODO consider a way to keep "external" FlowRules
            log.error("Lumentum NETCONF connection {} not in the cache", pair.getRight());
            rpcDeleteExternalConnection(moduleId, connId);
            return null;
        } else {
            //Update monitored values
            log.debug("Attenuation retrieved {} dB for connection {}",
                    attenuation, ((LumentumFlowRule) cacheRule).getConnectionId());
            ((LumentumFlowRule) cacheRule).setAttenuation(attenuation);
            ((LumentumFlowRule) cacheRule).setInputPower(inputPower);
            ((LumentumFlowRule) cacheRule).setOutputPower(outputPower);

            return cacheRule;
        }
    }

    /**
     * Get the port number.
     * If this is a MUX connection return input-port. Outport is always MUX_OUT = 4201.
     * If this is a DEMUX connection return output-port. Inport is always DEMUX_IN= 5101.
     *
     * @param module the module (1 for MUX/ADD, 2 for DEMUX/DROP)
     * @return the add/drop port number
     */
    private PortNumber getPortNumber(short module, String inputPort, String outputPort) {
        checkArgument(module == 1 || module == 2, "Module must be 1 (MUX/ADD) or 2 (DEMUX/DROP)");

        if (module == 1) {
            return PortNumber.portNumber(inputPort.split(DN_PORT)[1]);
        } else {
            return PortNumber.portNumber(outputPort.split(DN_PORT)[1]);
        }
    }

    /**
     * Converts cross connect flow rule to module and connection.
     *
     * Connection number is incremental within the class and associated to the rule hash.
     *
     * @param xc the cross connect flow rule
     * @return pair of module (1 for MUX/ADD, 2 for DEMUX/DROP) and connection number
     */
    private Pair<Short, Short> setModuleConnection(LumentumFlowRule xc, Integer id) {
        if (xc.isAddRule()) {
            xc.setConnectionModule((short) 1);
            xc.setConnectionId(id.shortValue());
            return Pair.of((short) 1, id.shortValue());
        } else {
            xc.setConnectionModule((short) 2);
            xc.setConnectionId(id.shortValue());
            return Pair.of((short) 2, id.shortValue());
        }
    }

    //Following Lumentum documentation rpc operation to configure a new connection
    private boolean rpcAddConnection(LumentumFlowRule xc) {

        int currentConnectionId = generateConnectionId();

        if (currentConnectionId == 0) {
            log.error("Lumentum driver - 100 connections are already configured on the device");
            return false;
        }

        Pair<Short, Short> pair = setModuleConnection(xc, currentConnectionId);
        String module = pair.getLeft().toString();
        String connectionId = pair.getRight().toString();

        //Conversion of ochSignal format (center frequency + diameter) to Lumentum frequency slot format (start - end)
        Frequency freqRadius = Frequency.ofHz(xc.ochSignal().channelSpacing().frequency().asHz() / 2);
        Frequency center = xc.ochSignal().centralFrequency();
        String startFreq = String.valueOf(center.subtract(freqRadius).asHz() / GHZ);
        String endFreq = String.valueOf(center.add(freqRadius).asHz() / GHZ);

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" + "\n");
        stringBuilder.append("<add-connection xmlns=\"http://www.lumentum.com/lumentum-ote-connection\">" + "\n");
        stringBuilder.append(
                "<dn>ne=1;chassis=1;card=1;module=" + module + ";connection=" + connectionId + "</dn>" + "\n");
        stringBuilder.append("<start-freq>" + startFreq + "</start-freq>" + "\n");
        stringBuilder.append("<end-freq>" + endFreq + "</end-freq>" + "\n");
        stringBuilder.append("<attenuation>" + "0.0" + "</attenuation>" + "\n");
        stringBuilder.append("<blocked>" + "false" + "</blocked>" + "\n");
        stringBuilder.append("<maintenance-state>" + "in-service" + "</maintenance-state>" + "\n");

        if (xc.isAddRule()) {
            stringBuilder.append(
                    "<input-port-reference>"  + DN_CARD1 + xc.addDrop().toString() + "</input-port-reference>" + "\n");
            stringBuilder.append(
                    "<output-port-reference>" + DN_CARD1 + MUX_OUT + "</output-port-reference>" + "\n");
        } else  {
            stringBuilder.append(
                    "<input-port-reference>"  + DN_CARD1 + DEMUX_IN + "</input-port-reference>" + "\n");
            stringBuilder.append(
                    "<output-port-reference>" + DN_CARD1 + xc.addDrop().toString() + "</output-port-reference>" + "\n");
        }
        stringBuilder.append("<custom-name>" + "onos-connection" + "</custom-name>" + "\n");
        stringBuilder.append("</add-connection>" + "\n");
        stringBuilder.append("</rpc>" + "\n");

        log.info("Lumentum ROADM20 - RPC add-connection sent to device {}", did());
        log.debug("Lumentum ROADM20 - RPC add-connection sent to device {} {}", did(), stringBuilder);

        return editCrossConnect(stringBuilder.toString());
    }

    //Following Lumentum documentation <edit-config> operation to edit connection parameter
    //Currently only edit the "attenuation" parameter
    private boolean editConnection(String moduleId, String connectionId, int attenuation) {

        double attenuationDouble = ((double) attenuation) / 100;

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" + "\n");
        stringBuilder.append("<edit-config>" + "\n");
        stringBuilder.append("<target>" + "\n");
        stringBuilder.append("<running/>" + "\n");
        stringBuilder.append("</target>" + "\n");
        stringBuilder.append("<config>" + "\n");
        stringBuilder.append("<connections xmlns=\"http://www.lumentum.com/lumentum-ote-connection\">" + "\n");
        stringBuilder.append("<connection>" + "\n");
        stringBuilder.append("" +
                "<dn>ne=1;chassis=1;card=1;module=" + moduleId + ";connection=" + connectionId + "</dn>" + "\n");
        //Other configurable parameters
        //stringBuilder.append("<custom-name/>" + "\n");
        //stringBuilder.append("<maintenance-state>" + "in-service" + "</maintenance-state>" + "\n");
        //stringBuilder.append("<start-freq>" + startFreq + "</start-freq>" + "\n");
        //stringBuilder.append("<end-freq>" + endFreq + "</end-freq>" + "\n");
        stringBuilder.append("<config>" + "\n");
        stringBuilder.append("<attenuation>" + attenuationDouble + "</attenuation>" + "\n");
        stringBuilder.append("</config>" + "\n");
        stringBuilder.append("</connection>" + "\n");
        stringBuilder.append("</connections>" + "\n");
        stringBuilder.append("</config>" + "\n");
        stringBuilder.append("</edit-config>" + "\n");
        stringBuilder.append("</rpc>" + "\n");

        log.info("Lumentum ROADM20 - edit-connection sent to device {}", did());
        log.debug("Lumentum ROADM20 - edit-connection sent to device {} {}", did(), stringBuilder);

        return editCrossConnect(stringBuilder.toString());
    }

    //Following Lumentum documentation rpc operation to delete a new connection
    private boolean rpcDeleteConnection(LumentumFlowRule xc) {

        //Look for corresponding rule into the cache
        FlowRule cacheRule = getConnectionCache().get(did()).stream()
                .filter(r -> (r.selector().equals(xc.selector()) && r.treatment().equals(xc.treatment())))
                .findFirst()
                .orElse(null);

        if (cacheRule == null) {
            log.error("Lumentum RPC delete-connection, connection not found on the local cache");
            throw new IllegalStateException("Lumentum RPC delete-connection, connection not found on the local cache");
        }


        int moduleId = ((LumentumFlowRule) cacheRule).getConnectionModule();
        int connId = ((LumentumFlowRule) cacheRule).getConnectionId();


        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" + "\n");
        stringBuilder.append("<delete-connection xmlns=\"http://www.lumentum.com/lumentum-ote-connection\">" + "\n");
        stringBuilder.append(
                "<dn>ne=1;chassis=1;card=1;module=" + moduleId + ";connection=" + connId + "</dn>" + "\n");
        stringBuilder.append("</delete-connection>" + "\n");
        stringBuilder.append("</rpc>" + " \n");

        log.info("Lumentum ROADM20 - RPC delete-connection sent to device {}", did());
        log.debug("Lumentum ROADM20 - - RPC delete-connection sent to device {} {}", did(), stringBuilder);

        return editCrossConnect(stringBuilder.toString());
    }

    //Following Lumentum documentation rpc operation to delete a new connection
    //Executed if for some reason a connection not in the cache is detected
    private boolean rpcDeleteExternalConnection(short moduleId, short connectionId) {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" + "\n");
        stringBuilder.append("<delete-connection xmlns=\"http://www.lumentum.com/lumentum-ote-connection\">" + "\n");
        stringBuilder.append("<dn>ne=1;chassis=1;card=1;module="
                + moduleId + ";connection=" + connectionId + "</dn>" + "\n");
        stringBuilder.append("</delete-connection>" + "\n");
        stringBuilder.append("</rpc>" + "\n");

        log.info("Lumentum ROADM20 - RPC delete-external-connection sent to device {}", did());
        log.debug("Lumentum ROADM20 - - RPC delete-external-connection sent to device {} {}", did(), stringBuilder);

        return editCrossConnect(stringBuilder.toString());
    }


    private boolean editCrossConnect(String xcString) {
        NetconfSession session = getNetconfSession();
        if (session == null) {
            log.error("Lumentum NETCONF - session not found for device {}", handler().data().deviceId());
            return false;
        }

        try {
            return session.editConfig(xcString);
        } catch (NetconfException e) {
            log.error("Failed to edit the CrossConnect edit-cfg for device {}",
                      handler().data().deviceId(), e);
            log.debug("Failed configuration {}", xcString);
            return false;
        }
    }

    /**
     * Convert start and end frequencies to OCh signal.
     *
     * FIXME: assumes slots of 12.5 GHz while devices allows granularity 6.25 GHz
     * FIXME: supports channel spacing 50 and 100
     *
     * @param start starting frequency as double in GHz
     * @param end end frequency as double in GHz
     * @return OCh signal
     */
    public static OchSignal toOchSignal(double start, double end) {
        int slots = (int) ((end - start) / ChannelSpacing.CHL_12P5GHZ.frequency().asGHz());
        int multiplier = 0;

        //Conversion for 50 GHz slots
        if (end - start == 50) {
            multiplier = (int) (((end - start) / 2 + start - Spectrum.CENTER_FREQUENCY.asGHz())
                    / ChannelSpacing.CHL_50GHZ.frequency().asGHz());

            return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, multiplier, slots);
        }

        //Conversion for 100 GHz slots
        if (end - start == 100) {
            multiplier = (int) (((end - start) / 2 + start - Spectrum.CENTER_FREQUENCY.asGHz())
                    / ChannelSpacing.CHL_100GHZ.frequency().asGHz());

            return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_100GHZ, multiplier, slots);
        }

        return null;
    }

    /**
     * Generate a valid connectionId, the connectionId is a field required by the device every time
     * a connection is created/edited/removed.
     *
     *
     * Device only supports connection id < 100
     */
    private int generateConnectionId() {
        //LUMENTUM_ROADM20_MAX_CONNECTIONS =  100, device only supports connection id < 100
        for (int i = 1; i < LUMENTUM_ROADM20_MAX_CONNECTIONS; i++) {
            Set<FlowRule> rulesForDevice = getConnectionCache().get(did());

            if (rulesForDevice == null) {
                return 1;
            } else {
                Set<Integer> connIds = rulesForDevice.stream()
                        .map(flow -> ((LumentumFlowRule) flow).getConnectionId())
                        .collect(Collectors.toSet());

                if (!connIds.contains(i)) {
                    return i;
                }
            }
        }
        return 0;
    }

    private DeviceConnectionCache getConnectionCache() {
        return DeviceConnectionCache.init();
    }

    /**
     * Helper method to get the device id.
     */
    private DeviceId did() {
        return data().deviceId();
    }

    /**
     * Helper method to get the Netconf session.
     */
    private NetconfSession getNetconfSession() {
        NetconfController controller =
                checkNotNull(handler().get(NetconfController.class));
        return controller.getNetconfDevice(did()).getSession();
    }
}
