/*
 * 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();

        // 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.info("Lumentum device, FlowRule coming from OpticalConnectivityIntentCompiler");

            type = Type.OPTICAL_CONNECTIVITY_INTENT_RULE;
        } else {
            log.info("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);

        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;
    }
}
