/*
* 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.openstacknetworking.switching;

import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.TpPort;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
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.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackSecurityGroup;
import org.onosproject.openstackinterface.OpenstackSecurityGroupRule;
import org.onosproject.openstacknetworking.OpenstackPortInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * Populates flows rules for Security Groups of VMs.
 *
 */
public class OpenstackSecurityGroupRulePopulator {

    private static Logger log = LoggerFactory
            .getLogger(OpenstackSecurityGroupRulePopulator.class);

    private OpenstackInterfaceService openstackService;
    private FlowObjectiveService flowObjectiveService;

    private ApplicationId appId;

    private static final String PROTO_ICMP = "ICMP";
    private static final String PROTO_TCP = "TCP";
    private static final String PROTO_UDP = "UDP";

    private static final String ETHTYPE_IPV4 = "IPV4";

    private static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0");

    private static final int ACL_RULE_PRIORITY = 30000;

    /**
     * Constructor.
     *
     * @param appId application ID
     * @param openstackService OpenStack interface service
     * @param flowObjectiveService flow objective service
     */
    public OpenstackSecurityGroupRulePopulator(ApplicationId appId, OpenstackInterfaceService openstackService,
                                               FlowObjectiveService flowObjectiveService) {
        this.appId = appId;
        this.openstackService = openstackService;
        this.flowObjectiveService = flowObjectiveService;
    }

    /**
     * Populates flow rules for security groups.
     *
     * @param id Device ID
     * @param sgId Security Group ID
     * @param vmIp VM IP address
     * @param portInfoMap Port Info map
     */
    public void populateSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp,
                                           Map<String, OpenstackPortInfo> portInfoMap) {
        OpenstackSecurityGroup securityGroup = openstackService.getSecurityGroup(sgId);
        if (securityGroup != null) {
            securityGroup.rules().stream().forEach(sgRule -> {
                if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) {
                    openstackService.ports().stream()
                        .filter(port -> port.securityGroups().contains(sgRule.remoteGroupId()))
                        .flatMap(port -> port.fixedIps().values().stream())
                        .forEach(remoteIp -> setSecurityGroupRule(id, sgRule,
                                vmIp, IpPrefix.valueOf((IpAddress) remoteIp, 32)));
                } else {
                    setSecurityGroupRule(id, sgRule, vmIp, sgRule.remoteIpPrefix());
                }
            });

            openstackService.ports().stream().forEach(osPort ->
                osPort.securityGroups().stream().forEach(remoteVmSgId -> {
                    OpenstackSecurityGroup remoteVmSg = openstackService.getSecurityGroup(remoteVmSgId);
                    remoteVmSg.rules().stream()
                        .filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId))
                        .forEach(remoteVmSgRule -> {
                            Ip4Address remoteVmIp =
                                    (Ip4Address) osPort.fixedIps().values().stream().findAny().orElse(null);
                            OpenstackPortInfo osPortInfo = portInfoMap.get(OpenstackSwitchingManager.PORTNAME_PREFIX_VM
                                    + osPort.id().substring(0, 11));
                            if (osPortInfo != null && remoteVmIp != null) {
                                setSecurityGroupRule(osPortInfo.deviceId(), remoteVmSgRule, remoteVmIp,
                                        IpPrefix.valueOf(vmIp, 32));
                            }
                        });
                }));
        }
    }

    /**
     * Removes flow rules for security groups.
     *
     * @param id Device ID
     * @param sgId Security Group ID to remove
     * @param vmIp VM IP address
     * @param portInfoMap port info map
     * @param securityGroupMap security group info map
     */
    public void removeSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp,
                                         Map<String, OpenstackPortInfo> portInfoMap,
                                         Map<String, OpenstackSecurityGroup> securityGroupMap) {
        OpenstackSecurityGroup securityGroup = securityGroupMap.get(sgId);
        if (securityGroup != null) {
            securityGroup.rules().stream().forEach(sgRule -> {
                if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) {
                    portInfoMap.values().stream()
                            .filter(portInfo -> portInfo.securityGroups().contains(sgRule.remoteGroupId()))
                            .map(OpenstackPortInfo::ip)
                            .forEach(remoteIp -> {
                                removeSecurityGroupRule(id, sgRule, vmIp, IpPrefix.valueOf(remoteIp, 32));
                            });
                } else {
                    removeSecurityGroupRule(id, sgRule, vmIp, sgRule.remoteIpPrefix());
                }
            });

            portInfoMap.values().stream()
                .forEach(portInfo -> portInfo.securityGroups()
                    .forEach(remoteVmSgId -> {
                        OpenstackSecurityGroup remoteVmSg = securityGroupMap.get(remoteVmSgId);
                        remoteVmSg.rules().stream()
                            .filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId))
                            .forEach(remoteVmSgRule -> removeSecurityGroupRule(portInfo.deviceId(),
                                    remoteVmSgRule, portInfo.ip(), IpPrefix.valueOf(vmIp, 32)));
                    }));
        }
    }

    private void setSecurityGroupRule(DeviceId id, OpenstackSecurityGroupRule sgRule,
                                      Ip4Address vmIp, IpPrefix remoteIp) {
        ForwardingObjective.Builder foBuilder = buildFlowObjective(id, sgRule, vmIp, remoteIp);
        if (foBuilder != null) {
            flowObjectiveService.forward(id, foBuilder.add());
        }
    }

    private void removeSecurityGroupRule(DeviceId id, OpenstackSecurityGroupRule sgRule,
                                      Ip4Address vmIp, IpPrefix remoteIp) {
        ForwardingObjective.Builder foBuilder = buildFlowObjective(id, sgRule, vmIp, remoteIp);
        if (foBuilder != null) {
            flowObjectiveService.forward(id, foBuilder.remove());
        }
    }

    ForwardingObjective.Builder buildFlowObjective(DeviceId id, OpenstackSecurityGroupRule sgRule,
                                           Ip4Address vmIp, IpPrefix remoteIp) {
        if (remoteIp != null && remoteIp.equals(IpPrefix.valueOf(vmIp, 32))) {
            return null;
        }
        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

        buildMatchs(sBuilder, sgRule, vmIp, remoteIp);

        ForwardingObjective.Builder foBuilder = DefaultForwardingObjective.builder()
                .withSelector(sBuilder.build())
                .withTreatment(tBuilder.build())
                .withPriority(ACL_RULE_PRIORITY)
                .withFlag(ForwardingObjective.Flag.SPECIFIC)
                .fromApp(appId);

        return foBuilder;
    }

    private void buildMatchs(TrafficSelector.Builder sBuilder, OpenstackSecurityGroupRule sgRule,
                             Ip4Address vmIp, IpPrefix remoteIp) {
        buildMatchEthType(sBuilder, sgRule.ethertype());
        buildMatchDirection(sBuilder, sgRule.direction(), vmIp);
        buildMatchProto(sBuilder, sgRule.protocol());
        buildMatchPort(sBuilder, sgRule.protocol(), sgRule.direction(), sgRule.portRangeMax(), sgRule.portRangeMin());
        buildMatchRemoteIp(sBuilder, remoteIp, sgRule.direction());
    }

    private void buildMatchDirection(TrafficSelector.Builder sBuilder,
                                     OpenstackSecurityGroupRule.Direction direction, Ip4Address vmIp) {
        if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) {
            sBuilder.matchIPSrc(IpPrefix.valueOf(vmIp, 32));
        } else {
            sBuilder.matchIPDst(IpPrefix.valueOf(vmIp, 32));
        }
    }

    private void buildMatchEthType(TrafficSelector.Builder sBuilder, String ethertype) {
        // Either IpSrc or IpDst (or both) is set by default, and we need to set EthType as IPv4.
        sBuilder.matchEthType(Ethernet.TYPE_IPV4);
        if (ethertype != null && ethertype != "null" &&
                !ethertype.toUpperCase().equals(ETHTYPE_IPV4)) {
            log.error("EthType {} is not supported yet in Security Group", ethertype);
        }
    }

    private void buildMatchRemoteIp(TrafficSelector.Builder sBuilder, IpPrefix remoteIpPrefix,
                                                       OpenstackSecurityGroupRule.Direction direction) {
        if (remoteIpPrefix != null && !remoteIpPrefix.getIp4Prefix().equals(IP_PREFIX_ANY)) {
            if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) {
                sBuilder.matchIPDst(remoteIpPrefix);
            } else {
                sBuilder.matchIPSrc(remoteIpPrefix);
            }
        }
    }

    private void buildMatchProto(TrafficSelector.Builder sBuilder, String protocol) {
        if (protocol != null) {
            switch (protocol.toUpperCase()) {
                case PROTO_ICMP:
                    sBuilder.matchIPProtocol(IPv4.PROTOCOL_ICMP);
                    break;
                case PROTO_TCP:
                    sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP);
                    break;
                case PROTO_UDP:
                    sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP);
                    break;
                default:
            }
        }
    }

    private void buildMatchPort(TrafficSelector.Builder sBuilder, String protocol,
                                                   OpenstackSecurityGroupRule.Direction direction,
                                                   int portMin, int portMax) {
        if (portMin > 0 && portMax > 0 && portMin == portMax) {
            if (protocol.toUpperCase().equals(PROTO_TCP)) {
                if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) {
                    sBuilder.matchTcpDst(TpPort.tpPort(portMax));
                } else {
                    sBuilder.matchTcpSrc(TpPort.tpPort(portMax));
                }
            } else if (protocol.toUpperCase().equals(PROTO_UDP)) {
                if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) {
                    sBuilder.matchUdpDst(TpPort.tpPort(portMax));
                } else {
                    sBuilder.matchUdpSrc(TpPort.tpPort(portMax));
                }
            }
        }
    }
}
