/*
* 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.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
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.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.openstacknetworking.AbstractVmHandler;
import org.onosproject.openstacknetworking.OpenstackSwitchingService;
import org.onosproject.openstacknetworking.RulePopulatorUtil;
import org.onosproject.openstacknode.OpenstackNodeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;
import java.util.Optional;

import static org.onosproject.openstacknetworking.Constants.*;
import static org.onosproject.openstacknetworking.RulePopulatorUtil.buildExtension;


/**
 * Populates switching flow rules.
 */
@Service
@Component(immediate = true)
public final class OpenstackSwitchingManager extends AbstractVmHandler
        implements OpenstackSwitchingService {

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowObjectiveService flowObjectiveService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected OpenstackNodeService nodeService;

    private ApplicationId appId;

    @Activate
    protected void activate() {
        super.activate();
        appId = coreService.registerApplication(SWITCHING_APP_ID);
    }

    @Deactivate
    protected void deactivate() {
        super.deactivate();
    }

    private void populateSwitchingRules(Host host) {
        setFlowRulesForTunnelTag(host, true);
        setFlowRulesForTrafficToSameCnode(host, true);
        setFlowRulesForTrafficToDifferentCnode(host, true);

        log.debug("Populated switching rule for {}", host);
    }

    private void removeSwitchingRules(Host host) {
        setFlowRulesForTunnelTag(host, false);
        setFlowRulesForTrafficToSameCnode(host, false);
        removeFlowRuleForVMsInDiffrentCnode(host);

        log.debug("Removed switching rule for {}", host);
    }

    private void setFlowRulesForTunnelTag(Host host, boolean install) {
        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                .matchInPort(host.location().port());

        tBuilder.setTunnelId(Long.valueOf(getVni(host)));

        RulePopulatorUtil.setRule(flowObjectiveService, appId, host.location().deviceId(),
                sBuilder.build(), tBuilder.build(), ForwardingObjective.Flag.SPECIFIC,
                TUNNELTAG_RULE_PRIORITY, install);
    }

    private void setFlowRulesForTrafficToSameCnode(Host host, boolean install) {
        //For L2 Switching Case
        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                .matchIPDst(getIp(host).toIpPrefix())
                .matchTunnelId(Long.valueOf(getVni(host)));

        // Destination setting is required for routing cases.
        // We do not believe the rule would not degrade the forwarding performance.
        // But, if it does, we need to move the rule in a separate routing table.
        tBuilder.setEthDst(host.mac())
                .setOutput(host.location().port());

        RulePopulatorUtil.setRule(flowObjectiveService, appId, host.location().deviceId(),
                sBuilder.build(), tBuilder.build(), ForwardingObjective.Flag.SPECIFIC,
                SWITCHING_RULE_PRIORITY, install);
    }

    private void setFlowRulesForTrafficToDifferentCnode(Host host, boolean install) {
        Ip4Address localVmIp = getIp(host);
        DeviceId localDeviceId = host.location().deviceId();
        Optional<IpAddress> localDataIp = nodeService.dataIp(localDeviceId);

        if (!localDataIp.isPresent()) {
            log.debug("Failed to get data IP for device {}",
                    host.location().deviceId());
            return;
        }

        String vni = getVni(host);
        getVmsInDifferentCnode(host).forEach(remoteVm -> {
            Optional<IpAddress> remoteDataIp = nodeService.dataIp(remoteVm.location().deviceId());
            if (remoteDataIp.isPresent()) {
                setVxLanFlowRule(vni,
                        localDeviceId,
                        remoteDataIp.get().getIp4Address(),
                        getIp(remoteVm), install);

                setVxLanFlowRule(vni,
                        remoteVm.location().deviceId(),
                        localDataIp.get().getIp4Address(),
                        localVmIp, install);
            }
        });
    }

    private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address remoteIp,
                                  Ip4Address vmIp, boolean install) {
        Optional<PortNumber> tunnelPort = nodeService.tunnelPort(deviceId);
        if (!tunnelPort.isPresent()) {
            log.warn("Failed to get tunnel port from {}", deviceId);
            return;
        }

        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                .matchTunnelId(Long.parseLong(vni))
                .matchIPDst(vmIp.toIpPrefix());
        tBuilder.extension(buildExtension(deviceService, deviceId, remoteIp), deviceId)
                .setOutput(tunnelPort.get());

        RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId,
                sBuilder.build(), tBuilder.build(), ForwardingObjective.Flag.SPECIFIC,
                SWITCHING_RULE_PRIORITY, install);
    }

    private void removeFlowRuleForVMsInDiffrentCnode(Host host) {
        DeviceId deviceId = host.location().deviceId();
        final boolean anyPortRemainedInSameCnode = hostService.getConnectedHosts(deviceId)
                .stream()
                .filter(this::isValidHost)
                .anyMatch(h -> Objects.equals(getVni(h), getVni(host)));

        getVmsInDifferentCnode(host).forEach(h -> {
            setVxLanFlowRule(getVni(host), h.location().deviceId(), getIp(host), Ip4Address.valueOf(0), false);
            if (!anyPortRemainedInSameCnode) {
                setVxLanFlowRule(getVni(host), deviceId, getIp(h), Ip4Address.valueOf(0), false);
            }
        });
    }

    @Override
    protected void hostDetected(Host host) {
        populateSwitchingRules(host);
        log.info("Added new virtual machine to switching service {}", host);
    }

    @Override
    protected void hostRemoved(Host host) {
        removeSwitchingRules(host);
        log.info("Removed virtual machine from switching service {}", host);
    }

    @Override
    public void reinstallVmFlow(Host host) {
        if (host == null) {
            hostService.getHosts().forEach(h -> {
                populateSwitchingRules(h);
                log.info("Re-Install data plane flow of virtual machine {}", h);
            });
        } else {
            populateSwitchingRules(host);
            log.info("Re-Install data plane flow of virtual machine {}", host);
        }
    }

    @Override
    public void purgeVmFlow(Host host) {
        if (host == null) {
            hostService.getHosts().forEach(h -> {
                removeSwitchingRules(h);
                log.info("Purge data plane flow of virtual machine {}", h);
            });
        } else {
            removeSwitchingRules(host);
            log.info("Purge data plane flow of virtual machine {}", host);
        }
    }
}
