/*
 * 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.pipelines.fabric.pipeliner;

import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
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.PiCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flowobjective.DefaultNextObjective;
import org.onosproject.net.flowobjective.NextObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.onosproject.net.group.DefaultGroupBucket;
import org.onosproject.net.group.DefaultGroupDescription;
import org.onosproject.net.group.DefaultGroupKey;
import org.onosproject.net.group.GroupBucket;
import org.onosproject.net.group.GroupBuckets;
import org.onosproject.net.group.GroupDescription;
import org.onosproject.net.group.GroupKey;
import org.onosproject.net.pi.runtime.PiAction;
import org.onosproject.net.pi.runtime.PiActionGroupId;
import org.onosproject.net.pi.runtime.PiActionParam;
import org.onosproject.net.pi.runtime.PiGroupKey;
import org.onosproject.pipelines.fabric.FabricConstants;
import org.onosproject.pipelines.fabric.FabricUtils;
import org.slf4j.Logger;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.onosproject.pipelines.fabric.FabricUtils.getOutputPort;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Handling next objective for fabric pipeliner.
 */
public class FabricNextPipeliner {
    private static final Logger log = getLogger(FabricNextPipeliner.class);
    private static final String NO_HASHED_TABLE = "noHashedTable";

    protected DeviceId deviceId;
    protected Driver driver;

    public FabricNextPipeliner(DeviceId deviceId, Driver driver) {
        this.deviceId = deviceId;
        this.driver = driver;
    }

    public PipelinerTranslationResult next(NextObjective nextObjective) {
        PipelinerTranslationResult.Builder resultBuilder = PipelinerTranslationResult.builder();

        if (nextObjective.op() != Objective.Operation.ADD_TO_EXISTING &&
                nextObjective.op() != Objective.Operation.REMOVE_FROM_EXISTING) {
            processNextVlanMeta(nextObjective, resultBuilder);
        }

        switch (nextObjective.type()) {
            case SIMPLE:
                processSimpleNext(nextObjective, resultBuilder);
                break;
            case HASHED:
                processHashedNext(nextObjective, resultBuilder);
                break;
            case BROADCAST:
                processBroadcastNext(nextObjective, resultBuilder);
                break;
            default:
                log.warn("Unsupported next type {}", nextObjective);
                resultBuilder.setError(ObjectiveError.UNSUPPORTED);
                break;
        }

        return resultBuilder.build();
    }

    private void processNextVlanMeta(NextObjective next,
                                     PipelinerTranslationResult.Builder resultBuilder) {
        TrafficSelector meta = next.meta();
        if (meta == null) {
            // do nothing if there is no metadata in the next objective.
            return;
        }
        VlanIdCriterion vlanIdCriterion =
                (VlanIdCriterion) meta.getCriterion(Criterion.Type.VLAN_VID);

        if (vlanIdCriterion == null) {
            // do nothing if we can't find vlan from next objective metadata.
            return;
        }

        VlanId vlanId = vlanIdCriterion.vlanId();
        TrafficSelector selector = buildNextIdSelector(next.id());
        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                .setVlanId(vlanId)
                .build();

        resultBuilder.addFlowRule(DefaultFlowRule.builder()
                                          .withSelector(selector)
                                          .withTreatment(treatment)
                                          .forTable(FabricConstants.FABRIC_INGRESS_NEXT_VLAN_META)
                                          .makePermanent()
                                          .withPriority(next.priority())
                                          .forDevice(deviceId)
                                          .fromApp(next.appId())
                                          .build());
    }

    private void processSimpleNext(NextObjective next,
                                   PipelinerTranslationResult.Builder resultBuilder) {

        if (next.next().size() > 1) {
            log.warn("Only one treatment in simple next objective");
            resultBuilder.setError(ObjectiveError.BADPARAMS);
            return;
        }

        TrafficSelector selector = buildNextIdSelector(next.id());
        TrafficTreatment treatment = next.next().iterator().next();
        PortNumber outputPort = getOutputPort(treatment);

        if (outputPort == null) {
            log.warn("At least one output instruction in simple next objective");
            resultBuilder.setError(ObjectiveError.BADPARAMS);
            return;
        }

        resultBuilder.addFlowRule(DefaultFlowRule.builder()
                                          .withSelector(selector)
                                          .withTreatment(treatment)
                                          .forTable(FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE)
                                          .makePermanent()
                                          .withPriority(next.priority())
                                          .forDevice(deviceId)
                                          .fromApp(next.appId())
                                          .build());

        if (includesPopVlanInst(treatment)) {
            processVlanPopRule(outputPort, next, resultBuilder);
        }
    }

    private boolean includesPopVlanInst(TrafficTreatment treatment) {
        return treatment.allInstructions()
                .stream()
                .filter(inst -> inst.type() == Instruction.Type.L2MODIFICATION)
                .map(inst -> (L2ModificationInstruction) inst)
                .anyMatch(inst -> inst.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP);
    }

    private void processVlanPopRule(PortNumber port, NextObjective next,
                                    PipelinerTranslationResult.Builder resultBuilder) {
        TrafficSelector meta = next.meta();
        VlanIdCriterion vlanIdCriterion =
                (VlanIdCriterion) meta.getCriterion(Criterion.Type.VLAN_VID);
        VlanId vlanId = vlanIdCriterion.vlanId();

        PiCriterion egressVlanTableMatch = PiCriterion.builder()
                .matchExact(FabricConstants.STANDARD_METADATA_EGRESS_PORT,
                            (short) port.toLong())
                .build();
        // Add VLAN pop rule to egress pipeline table
        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchPi(egressVlanTableMatch)
                .matchVlanId(vlanId)
                .build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                .popVlan()
                .build();
        resultBuilder.addFlowRule(DefaultFlowRule.builder()
                                          .withSelector(selector)
                                          .withTreatment(treatment)
                                          .forTable(FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN)
                                          .makePermanent()
                                          .withPriority(next.priority())
                                          .forDevice(deviceId)
                                          .fromApp(next.appId())
                                          .build());
    }

    private void processHashedNext(NextObjective next, PipelinerTranslationResult.Builder resultBuilder) {
        boolean noHashedTable = Boolean.parseBoolean(driver.getProperty(NO_HASHED_TABLE));

        if (noHashedTable) {
            if (next.next().isEmpty()) {
                return;
            }
            // use first action if not support hashed group
            TrafficTreatment treatment = next.next().iterator().next();

            NextObjective.Builder simpleNext = DefaultNextObjective.builder()
                    .addTreatment(treatment)
                    .withId(next.id())
                    .fromApp(next.appId())
                    .makePermanent()
                    .withMeta(next.meta())
                    .withPriority(next.priority())
                    .withType(NextObjective.Type.SIMPLE);

            if (next.context().isPresent()) {
                processSimpleNext(simpleNext.add(next.context().get()), resultBuilder);
            } else {
                processSimpleNext(simpleNext.add(), resultBuilder);
            }
            return;
        }

        // create hash groups
        int groupId = next.id();
        List<GroupBucket> bucketList = next.next().stream()
                .map(DefaultGroupBucket::createSelectGroupBucket)
                .collect(Collectors.toList());

        // Egress VLAN handling
        next.next().forEach(treatment -> {
            PortNumber outputPort = getOutputPort(treatment);
            if (includesPopVlanInst(treatment) && outputPort != null) {
                processVlanPopRule(outputPort, next, resultBuilder);
            }
        });

        if (bucketList.size() != next.next().size()) {
            // some action not converted
            // set error
            log.warn("Expected bucket size {}, got {}", next.next().size(), bucketList.size());
            resultBuilder.setError(ObjectiveError.BADPARAMS);
            return;
        }

        GroupBuckets buckets = new GroupBuckets(bucketList);
        PiGroupKey groupKey = new PiGroupKey(FabricConstants.FABRIC_INGRESS_NEXT_HASHED,
                                             FabricConstants.FABRIC_INGRESS_NEXT_ECMP_SELECTOR,
                                             groupId);

        resultBuilder.addGroup(new DefaultGroupDescription(deviceId,
                                                           GroupDescription.Type.SELECT,
                                                           buckets,
                                                           groupKey,
                                                           groupId,
                                                           next.appId()));

        // flow
        // If operation is ADD_TO_EXIST or REMOVE_FROM_EXIST, means we modify
        // group buckets only, no changes for flow rule
        if (next.op() == Objective.Operation.ADD_TO_EXISTING ||
                next.op() == Objective.Operation.REMOVE_FROM_EXISTING) {
            return;
        }
        TrafficSelector selector = buildNextIdSelector(next.id());
        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                .piTableAction(PiActionGroupId.of(next.id()))
                .build();

        resultBuilder.addFlowRule(DefaultFlowRule.builder()
                                          .withSelector(selector)
                                          .withTreatment(treatment)
                                          .forTable(FabricConstants.FABRIC_INGRESS_NEXT_HASHED)
                                          .makePermanent()
                                          .withPriority(next.priority())
                                          .forDevice(deviceId)
                                          .fromApp(next.appId())
                                          .build());
    }

    private TrafficSelector buildNextIdSelector(int nextId) {
        PiCriterion nextIdCriterion = PiCriterion.builder()
                .matchExact(FabricConstants.FABRIC_METADATA_NEXT_ID, nextId)
                .build();
        return DefaultTrafficSelector.builder()
                .matchPi(nextIdCriterion)
                .build();
    }

    private void processBroadcastNext(NextObjective next, PipelinerTranslationResult.Builder resultBuilder) {
        final GroupDescription allGroup = getAllGroup(next);
        if (allGroup == null) {
            // Error already logged.
            resultBuilder.setError(ObjectiveError.BADPARAMS);
            return;
        }

        resultBuilder.addGroup(allGroup);
        //flow rule
        final TrafficSelector selector = buildNextIdSelector(next.id());
        final PiActionParam groupIdParam = new PiActionParam(
                FabricConstants.GID, allGroup.givenGroupId());

        final PiAction setMcGroupAction = PiAction.builder()
                .withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_MCAST_GROUP)
                .withParameter(groupIdParam)
                .build();
        final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                .piTableAction(setMcGroupAction)
                .build();

        resultBuilder.addFlowRule(
                DefaultFlowRule.builder()
                        .withSelector(selector)
                        .withTreatment(treatment)
                        .forTable(FabricConstants.FABRIC_INGRESS_NEXT_MULTICAST)
                        .makePermanent()
                        .withPriority(next.priority())
                        .forDevice(deviceId)
                        .fromApp(next.appId())
                        .build());

        // Egress VLAN handling
        next.next().forEach(t -> {
            PortNumber outputPort = getOutputPort(t);
            if (includesPopVlanInst(t) && outputPort != null) {
                processVlanPopRule(outputPort, next, resultBuilder);
            }
            if (t.allInstructions().size() > 2) {
                // More than OUTPUT and VLAN_POP...
                log.warn("Some instructions of BROADCAST NextObjective might" +
                                 "not have been applied, supported only " +
                                 "OUTPUT and VLAN_POP, but found {}", t);
            }
        });
    }

    private GroupDescription getAllGroup(NextObjective next) {
        final List<GroupBucket> bucketList = next.next().stream()
                .map(FabricUtils::getOutputInstruction)
                .filter(Optional::isPresent)
                .map(Optional::get)
                .map(i -> DefaultTrafficTreatment.builder().add(i).build())
                .map(DefaultGroupBucket::createAllGroupBucket)
                .collect(Collectors.toList());

        if (bucketList.size() != next.next().size()) {
            log.warn("Got BROADCAST NextObjective with {} treatments but " +
                             "found only {} OUTPUT instructions, cannot " +
                             "translate to ALL groups",
                     next.next().size(), bucketList.size());
            return null;
        }

        // FIXME: remove once support for clone sessions is available
        // Right now we add a CPU port to all multicast groups. The egress
        // pipeline is expected to drop replicated packets to the CPU if a clone
        // was  not requested in the ingress pipeline.
        bucketList.add(
                DefaultGroupBucket.createAllGroupBucket(
                        DefaultTrafficTreatment.builder()
                                .setOutput(PortNumber.CONTROLLER)
                                .build()));

        final int groupId = next.id();
        final GroupBuckets buckets = new GroupBuckets(bucketList);
        // Used DefaultGroupKey instead of PiGroupKey
        // as we don't have any action profile to apply to the groups of ALL type
        final GroupKey groupKey = new DefaultGroupKey(FabricPipeliner.KRYO.serialize(groupId));

        return new DefaultGroupDescription(deviceId,
                                           GroupDescription.Type.ALL,
                                           buckets,
                                           groupKey,
                                           groupId,
                                           next.appId());
    }
}
