/*
 * 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 org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.OchSignalCriterion;
import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;

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

public class LumentumFlowRule extends DefaultFlowRule {
    private static final Logger log = LoggerFactory.getLogger(LumentumFlowRule.class);

    protected enum Type {
        OPTICAL_CONNECTIVITY_INTENT_RULE,
        ROADM_APP_RULE
    }
    public Type type;

    private String connectionName;
    private int connectionId;
    private int connectionModule;
    private PortNumber addDrop;

    private PortNumber inputPort;
    private PortNumber outputPort;

    private OchSignal ochSignal;
    private boolean isAddRule;

    protected double attenuation;
    protected double targetAttenuation;
    protected double targetPower;
    protected double inputPower;
    protected double outputPower;

    //As generated by the OpticalConnectivityIntentCompiler
    private static final int NUM_CRITERIA_INTENT = 3;
    private static final int NUM_INSTRUCTIONS_INTENT = 2;

    //As generated dy ROADM app
    private static final int NUM_CRITERIA_ROADM = 3;
    private static final int NUM_INSTRUCTIONS_ROADM = 1;


    public LumentumFlowRule(FlowRule rule, List<PortNumber> linePorts) {
        super(rule);

        Set<Criterion> criteria = rule.selector().criteria();
        List<Instruction> instructions = rule.treatment().immediate();

        log.debug("Lumentum device received criteria {} - treatment {}",
                criteria,
                instructions);

        // Proper cross connect has criteria for input port, OChSignal and OCh signal type.
        // Instruction is only output to port (rule generated by ROADM app).
        // Instruction includes output port and OChSignal (rule generated by OpticalConnectivityIntent).
        checkArgument((criteria.size() == NUM_CRITERIA_INTENT) ||
                        (criteria.size() == NUM_CRITERIA_ROADM),
                "Wrong size of flow rule criteria for cross connect.");
        checkArgument((instructions.size() == NUM_INSTRUCTIONS_INTENT) ||
                        (instructions.size() == NUM_INSTRUCTIONS_ROADM),
                "Wrong size of flow rule instructions for cross connect.");

        // FIXME: Ensure criteria has exactly one of each match type
        criteria.forEach(
                c -> checkArgument(c instanceof OchSignalCriterion ||
                                c instanceof OchSignalTypeCriterion ||
                                c instanceof PortCriterion,
                        "Incompatible flow rule criteria for LumentumROADM: " + criteria
                )
        );

        instructions.forEach(
                c -> checkArgument(c instanceof Instructions.OutputInstruction ||
                        c instanceof L0ModificationInstruction,
                        "Incompatible flow rule instruction for LumentumROADM: " + instructions
                )
        );

        if (criteria.size() == NUM_CRITERIA_INTENT && instructions.size() == NUM_INSTRUCTIONS_INTENT) {
            log.debug("Lumentum device, FlowRule coming from OpticalConnectivityIntentCompiler");

            type = Type.OPTICAL_CONNECTIVITY_INTENT_RULE;
        } else {
            log.debug("Lumentum device, FlowRule coming from ROADM app");

            type = Type.ROADM_APP_RULE;
        }

        ochSignal = criteria.stream()
                .filter(c -> c instanceof OchSignalCriterion)
                .map(c -> ((OchSignalCriterion) c).lambda())
                .findAny()
                .orElse(null);

        checkArgument(ochSignal.slotGranularity() == 4 || ochSignal.slotGranularity() == 8,
        "Lumentum device, only supports 50 GHz and 100 GHz frequency slots");

        inputPort = criteria.stream()
                .filter(c -> c instanceof PortCriterion)
                .map(c -> ((PortCriterion) c).port())
                .findAny()
                .orElse(null);

        outputPort = instructions.stream()
                .filter(c -> c instanceof Instructions.OutputInstruction)
                .map(c -> ((Instructions.OutputInstruction) c).port())
                .findAny()
                .orElse(null);

        // Add or drop rule? Get the output instruction
        Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) instructions.stream()
                .filter(c -> c instanceof Instructions.OutputInstruction)
                .findAny()
                .orElse(null);

        if (linePorts.contains(outInstruction.port())) {
            addDrop = criteria.stream()
                    .filter(c -> c instanceof PortCriterion)
                    .map(c -> ((PortCriterion) c).port())
                    .findAny()
                    .orElse(null);
            isAddRule = true;
        } else {
            addDrop = outInstruction.port();
            isAddRule = false;
        }

        connectionName =  "inPort" + inputPort.toString() + "-ochSig-" + ochSignal.centralFrequency().toString();
    }

    public PortNumber addDrop() {
        return addDrop;
    }

    public OchSignal ochSignal() {
        return ochSignal;
    }

    public boolean isAddRule() {
        return isAddRule;
    }

    public PortNumber getInputPort() {
        return inputPort;
    }

    public PortNumber getOutputPort() {
        return outputPort;
    }

    public String getConnectionName() {
        return connectionName;
    }

    public int getConnectionId() {
        return connectionId;
    }

    public int getConnectionModule() {
        return connectionModule;
    }

    public void setConnectionId(int id) {
        connectionId = id;
    }

    public void setConnectionModule(int id) {
        connectionModule = id;
    }

    protected void setAttenuation(double att) {
        attenuation = att;
    }

    protected void setInputPower(double power) {
        inputPower = power;
    }

    protected void setOutputPower(double power) {
        outputPower = power;
    }
}
