/*
 * 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.bmv2.ctl;

import com.google.common.annotations.Beta;
import com.google.common.collect.Sets;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.bmv2.api.context.Bmv2ActionModel;
import org.onosproject.bmv2.api.context.Bmv2Configuration;
import org.onosproject.bmv2.api.context.Bmv2DeviceContext;
import org.onosproject.bmv2.api.context.Bmv2FieldModel;
import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator;
import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslatorException;
import org.onosproject.bmv2.api.context.Bmv2Interpreter;
import org.onosproject.bmv2.api.context.Bmv2InterpreterException;
import org.onosproject.bmv2.api.context.Bmv2RuntimeDataModel;
import org.onosproject.bmv2.api.context.Bmv2TableKeyModel;
import org.onosproject.bmv2.api.context.Bmv2TableModel;
import org.onosproject.bmv2.api.runtime.Bmv2Action;
import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam;
import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector;
import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment;
import org.onosproject.bmv2.api.runtime.Bmv2LpmMatchParam;
import org.onosproject.bmv2.api.runtime.Bmv2MatchKey;
import org.onosproject.bmv2.api.runtime.Bmv2MatchParam;
import org.onosproject.bmv2.api.runtime.Bmv2TableEntry;
import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam;
import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.ExtensionCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.Instructions.ExtensionInstructionWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.roundToBytes;
import static org.onosproject.net.flow.criteria.Criterion.Type.EXTENSION;
import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.BMV2_MATCH_PARAMS;

/**
 * Default implementation of a BMv2 flow rule translator.
 */
@Beta
public class Bmv2FlowRuleTranslatorImpl implements Bmv2FlowRuleTranslator {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    public Bmv2TableEntry translate(FlowRule rule, Bmv2DeviceContext context)
            throws Bmv2FlowRuleTranslatorException {

        Bmv2Configuration configuration = context.configuration();
        Bmv2Interpreter interpreter = context.interpreter();

        int tableId = rule.tableId();
        String tableName = interpreter.tableIdMap().get(tableId);

        Bmv2TableModel table = (tableName == null) ? configuration.table(tableId) : configuration.table(tableName);

        if (table == null) {
            throw new Bmv2FlowRuleTranslatorException("Unknown table ID: " + tableId);
        }

        /* Translate selector */
        Bmv2MatchKey bmv2MatchKey = buildMatchKey(interpreter, rule.selector(), table);

        /* Translate treatment */
        TrafficTreatment treatment = rule.treatment();
        Bmv2Action bmv2Action = null;
        // If treatment has only 1 instruction of type extension, use that
        for (Instruction inst : treatment.allInstructions()) {
            if (inst.type() == Instruction.Type.EXTENSION) {
                if (treatment.allInstructions().size() == 1) {
                    bmv2Action = getActionFromExtension((ExtensionInstructionWrapper) inst);
                } else {
                    throw new Bmv2FlowRuleTranslatorException("Unable to translate traffic treatment, found multiple " +
                                                                      "instructions of which one is an extension: " +
                                                                      treatment.toString());
                }
            }
        }

        if (bmv2Action == null) {
            // No extension, use interpreter to build action.
            try {
                bmv2Action = interpreter.mapTreatment(treatment, configuration);
            } catch (Bmv2InterpreterException e) {
                throw new Bmv2FlowRuleTranslatorException("Unable to translate treatment. " + e.toString());
            }
        }

        if (bmv2Action == null) {
            // Interpreter returned null.
            throw new Bmv2FlowRuleTranslatorException("Unable to translate treatment");
        }

        // Check action
        Bmv2ActionModel actionModel = configuration.action(bmv2Action.name());
        if (actionModel == null) {
            throw new Bmv2FlowRuleTranslatorException("Unknown action " + bmv2Action.name());
        }
        if (!table.actions().contains(actionModel)) {
            throw new Bmv2FlowRuleTranslatorException("Action " + bmv2Action.name()
                                                              + " is not defined for table " + tableName);
        }
        if (actionModel.runtimeDatas().size() != bmv2Action.parameters().size()) {
            throw new Bmv2FlowRuleTranslatorException("Wrong number of parameters for action "
                                                              + actionModel.name() + ", expected "
                                                              + actionModel.runtimeDatas().size() + ", but found "
                                                              + bmv2Action.parameters().size());
        }
        for (int i = 0; i < actionModel.runtimeDatas().size(); i++) {
            Bmv2RuntimeDataModel data = actionModel.runtimeDatas().get(i);
            ImmutableByteSequence param = bmv2Action.parameters().get(i);
            if (param.size() != roundToBytes(data.bitWidth())) {
                throw new Bmv2FlowRuleTranslatorException("Wrong byte-width for parameter " + data.name()
                                                                  + " of action " + actionModel.name()
                                                                  + ", expected " + roundToBytes(data.bitWidth())
                                                                  + " bytes, but found " + param.size());
            }
        }

        Bmv2TableEntry.Builder tableEntryBuilder = Bmv2TableEntry.builder();

        // In BMv2 0 is the highest priority.
        int newPriority = Integer.MAX_VALUE - rule.priority();

        tableEntryBuilder
                .withTableName(table.name())
                .withPriority(newPriority)
                .withMatchKey(bmv2MatchKey)
                .withAction(bmv2Action);

        if (!rule.isPermanent()) {
            if (table.hasTimeouts()) {
                tableEntryBuilder.withTimeout((double) rule.timeout());
            } else {
                log.warn("Flow rule is temporary but table {} doesn't support timeouts, translating to permanent",
                         table.name());
            }

        }

        return tableEntryBuilder.build();
    }

    private Bmv2TernaryMatchParam buildTernaryParam(Bmv2FieldModel field, Criterion criterion, int bitWidth)
            throws Bmv2FlowRuleTranslatorException {

        // Value and mask will be filled according to criterion type
        ImmutableByteSequence value;
        ImmutableByteSequence mask = null;

        int byteWidth = roundToBytes(bitWidth);

        switch (criterion.type()) {
            case IN_PORT:
                long port = ((PortCriterion) criterion).port().toLong();
                value = ImmutableByteSequence.copyFrom(port);
                break;
            case ETH_DST:
                EthCriterion c = (EthCriterion) criterion;
                value = ImmutableByteSequence.copyFrom(c.mac().toBytes());
                if (c.mask() != null) {
                    mask = ImmutableByteSequence.copyFrom(c.mask().toBytes());
                }
                break;
            case ETH_SRC:
                EthCriterion c2 = (EthCriterion) criterion;
                value = ImmutableByteSequence.copyFrom(c2.mac().toBytes());
                if (c2.mask() != null) {
                    mask = ImmutableByteSequence.copyFrom(c2.mask().toBytes());
                }
                break;
            case ETH_TYPE:
                short ethType = ((EthTypeCriterion) criterion).ethType().toShort();
                value = ImmutableByteSequence.copyFrom(ethType);
                break;
            // TODO: implement building for other criterion types (easy with DefaultCriterion of ONOS-4034)
            default:
                throw new Bmv2FlowRuleTranslatorException("Feature not implemented, ternary builder for criterion" +
                                                                  "type: " + criterion.type().name());
        }

        // Fit byte sequence in field model bit-width.
        try {
            value = Bmv2TranslatorUtils.fitByteSequence(value, bitWidth);
        } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) {
            throw new Bmv2FlowRuleTranslatorException(
                    "Fit exception for criterion " + criterion.type().name() + " value, " + e.getMessage());
        }

        if (mask == null) {
            // no mask, all ones
            mask = ImmutableByteSequence.ofOnes(byteWidth);
        } else {
            try {
                mask = Bmv2TranslatorUtils.fitByteSequence(mask, bitWidth);
            } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) {
                throw new Bmv2FlowRuleTranslatorException(
                        "Fit exception for criterion " + criterion.type().name() + " mask, " + e.getMessage());
            }
        }

        return new Bmv2TernaryMatchParam(value, mask);
    }

    private Bmv2Action getActionFromExtension(Instructions.ExtensionInstructionWrapper inst)
            throws Bmv2FlowRuleTranslatorException {

        ExtensionTreatment extTreatment = inst.extensionInstruction();

        if (extTreatment.type() == ExtensionTreatmentTypes.BMV2_ACTION.type()) {
            if (extTreatment instanceof Bmv2ExtensionTreatment) {
                return ((Bmv2ExtensionTreatment) extTreatment).getAction();
            } else {
                throw new Bmv2FlowRuleTranslatorException("Unable to decode treatment extension: " + extTreatment);
            }
        } else {
            throw new Bmv2FlowRuleTranslatorException("Unsupported treatment extension type: " + extTreatment.type());
        }
    }

    private Bmv2MatchKey buildMatchKey(Bmv2Interpreter interpreter, TrafficSelector selector, Bmv2TableModel tableModel)
            throws Bmv2FlowRuleTranslatorException {

        // Find a bmv2 extension selector (if any) and get the parameter map.
        Optional<Bmv2ExtensionSelector> extSelector = selector.criteria().stream()
                .filter(c -> c.type().equals(EXTENSION))
                .map(c -> (ExtensionCriterion) c)
                .map(ExtensionCriterion::extensionSelector)
                .filter(c -> c.type().equals(BMV2_MATCH_PARAMS.type()))
                .map(c -> (Bmv2ExtensionSelector) c)
                .findFirst();
        Map<String, Bmv2MatchParam> extParamMap =
                (extSelector.isPresent()) ? extSelector.get().parameterMap() : Collections.emptyMap();

        Set<Criterion> translatedCriteria = Sets.newHashSet();
        Set<String> usedExtParams = Sets.newHashSet();

        Bmv2MatchKey.Builder matchKeyBuilder = Bmv2MatchKey.builder();

        keysLoop:
        for (Bmv2TableKeyModel keyModel : tableModel.keys()) {

            // use fieldName dot notation (e.g. ethernet.dstAddr)
            String fieldName = keyModel.field().header().name() + "." + keyModel.field().type().name();

            int bitWidth = keyModel.field().type().bitWidth();
            int byteWidth = roundToBytes(bitWidth);

            Criterion.Type criterionType = interpreter.criterionTypeMap().inverse().get(fieldName);

            if (!extParamMap.containsKey(fieldName) &&
                    (criterionType == null || selector.getCriterion(criterionType) == null)) {
                // Neither an extension nor a mapping / criterion is available for this field.
                switch (keyModel.matchType()) {
                    case TERNARY:
                        // Wildcard field
                        matchKeyBuilder.withWildcard(byteWidth);
                        break;
                    case LPM:
                        // LPM with prefix 0
                        matchKeyBuilder.add(new Bmv2LpmMatchParam(ImmutableByteSequence.ofZeros(byteWidth), 0));
                        break;
                    default:
                        throw new Bmv2FlowRuleTranslatorException("No value found for required match field "
                                                                          + fieldName);
                }
                // Next key
                continue keysLoop;
            }

            Bmv2MatchParam matchParam;

            if (extParamMap.containsKey(fieldName)) {
                // Parameter found in extension
                if (criterionType != null && selector.getCriterion(criterionType) != null) {
                    // Found also a criterion that can be mapped. This is bad.
                    throw new Bmv2FlowRuleTranslatorException("Both an extension and a criterion mapping are defined " +
                                                                      "for match field " + fieldName);
                }

                matchParam = extParamMap.get(fieldName);
                usedExtParams.add(fieldName);

                // Check parameter type and size
                if (!keyModel.matchType().equals(matchParam.type())) {
                    throw new Bmv2FlowRuleTranslatorException("Wrong match type for parameter " + fieldName
                                                                      + ", expected " + keyModel.matchType().name()
                                                                      + ", but found " + matchParam.type().name());
                }
                int foundByteWidth;
                switch (keyModel.matchType()) {
                    case EXACT:
                        Bmv2ExactMatchParam m1 = (Bmv2ExactMatchParam) matchParam;
                        foundByteWidth = m1.value().size();
                        break;
                    case TERNARY:
                        Bmv2TernaryMatchParam m2 = (Bmv2TernaryMatchParam) matchParam;
                        foundByteWidth = m2.value().size();
                        break;
                    case LPM:
                        Bmv2LpmMatchParam m3 = (Bmv2LpmMatchParam) matchParam;
                        foundByteWidth = m3.value().size();
                        break;
                    case VALID:
                        foundByteWidth = -1;
                        break;
                    default:
                        // should never be her
                        throw new RuntimeException("Unrecognized match type " + keyModel.matchType().name());
                }
                if (foundByteWidth != -1 && foundByteWidth != byteWidth) {
                    throw new Bmv2FlowRuleTranslatorException("Wrong byte-width for match parameter " + fieldName
                                                                      + ", expected " + byteWidth + ", but found "
                                                                      + foundByteWidth);
                }

            } else {
                // A criterion mapping is available for this key
                Criterion criterion = selector.getCriterion(criterionType);
                translatedCriteria.add(criterion);
                switch (keyModel.matchType()) {
                    case TERNARY:
                        matchParam = buildTernaryParam(keyModel.field(), criterion, bitWidth);
                        break;
                    default:
                        // TODO: implement other match param builders (exact, LPM, etc.)
                        throw new Bmv2FlowRuleTranslatorException("Feature not yet implemented, match param builder: "
                                                                          + keyModel.matchType().name());
                }
            }

            matchKeyBuilder.add(matchParam);
        }

        // Check if all criteria have been translated
        Set<Criterion> ignoredCriteria = selector.criteria()
                .stream()
                .filter(c -> !c.type().equals(EXTENSION))
                .filter(c -> !translatedCriteria.contains(c))
                .collect(Collectors.toSet());

        if (ignoredCriteria.size() > 0) {
            throw new Bmv2FlowRuleTranslatorException("The following criteria cannot be translated for table "
                                                              + tableModel.name() + ": " + ignoredCriteria.toString());
        }

        // Check is all extension parameters have been used
        Set<String> ignoredExtParams = extParamMap.keySet()
                .stream()
                .filter(k -> !usedExtParams.contains(k))
                .collect(Collectors.toSet());

        if (ignoredExtParams.size() > 0) {
            throw new Bmv2FlowRuleTranslatorException("The following extension match parameters cannot be used for " +
                                                              "table " + tableModel.name() + ": "
                                                              + ignoredExtParams.toString());
        }

        return matchKeyBuilder.build();
    }

}
