/*
 * 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.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 java.util.List;
import java.util.Set;

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

/**
 * Cross connect abstraction based on a flow rule.
 */
public class CrossConnectFlowRule extends DefaultFlowRule implements CrossConnect {
    private PortNumber addDrop;
    private OchSignal ochSignal;
    private boolean isAddRule;

    public CrossConnectFlowRule(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 must be output to port.
        checkArgument(criteria.size() == 3, "Wrong size of flow rule criteria for cross connect.");
        checkArgument(instructions.size() == 1, "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 cross connect: " + criteria
                )
        );
        checkArgument(instructions.get(0).type() == Instruction.Type.OUTPUT,
                "Incompatible flow rule instructions for cross connect: " + instructions);

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

        // Add or drop rule?
        Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) instructions.get(0);
        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;
        }
    }

    @Override
    public PortNumber addDrop() {
        return addDrop;
    }

    @Override
    public OchSignal ochSignal() {
        return ochSignal;
    }

    @Override
    public boolean isAddRule() {
        return isAddRule;
    }
}
