/*
 * 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.sfc.installer.impl;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.Device.Type.SWITCH;
import static org.onosproject.net.Port.Type.COPPER;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.NshServicePathId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.host.HostService;
import org.onosproject.net.host.HostServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.sfc.util.FlowClassifierAdapter;
import org.onosproject.sfc.util.FlowObjectiveAdapter;
import org.onosproject.sfc.util.MockDriverHandler;
import org.onosproject.sfc.util.PortPairAdapter;
import org.onosproject.sfc.util.PortPairGroupAdapter;
import org.onosproject.sfc.util.TenantNetworkAdapter;
import org.onosproject.sfc.util.VirtualPortAdapter;
import org.onosproject.sfc.util.VtnRscAdapter;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultFiveTuple;
import org.onosproject.vtnrsc.DefaultFlowClassifier;
import org.onosproject.vtnrsc.DefaultPortChain;
import org.onosproject.vtnrsc.DefaultPortPair;
import org.onosproject.vtnrsc.DefaultPortPairGroup;
import org.onosproject.vtnrsc.DefaultTenantNetwork;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FiveTuple;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.LoadBalanceId;
import org.onosproject.vtnrsc.PhysicalNetwork;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairGroupId;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
import org.onosproject.vtnrsc.portpair.PortPairService;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

public class SfcFlowRuleInstallerImplTest {

    FlowObjectiveService flowObjectiveService = new FlowObjectiveAdapter();
    DeviceService deviceService = new DeviceServiceAdapter(createPortList());

    HostService hostService = new HostServiceAdapter();
    VirtualPortService virtualPortService = new VirtualPortAdapter();
    VtnRscService vtnRscService = new VtnRscAdapter();
    PortPairService portPairService = new PortPairAdapter();
    PortPairGroupService portPairGroupService = new PortPairGroupAdapter();
    FlowClassifierService flowClassifierService = new FlowClassifierAdapter();
    TenantNetworkService tenantNetworkService = new TenantNetworkAdapter();

    final DriverService driverService = createMock(DriverService.class);

    private final String networkIdStr = "123";

    final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
    final TenantId tenantId = TenantId.tenantId("1");
    final String name = "PortChain";
    final String description = "PortChain";
    final List<PortPairGroupId> portPairGroups = new LinkedList<PortPairGroupId>();
    final List<FlowClassifierId> flowClassifiers = new LinkedList<FlowClassifierId>();
    PortPairGroupId portPairGroupId1 = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
    PortPairGroupId portPairGroupId2 = PortPairGroupId.of("73343531-fc23-aeb6-f44b-56dc5e2fb3af");

    PortPairId portPairId1 = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
    PortPairId portPairId2 = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");

    FlowClassifierId flowClassifierId1 = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
    FlowClassifierId flowClassifierId2 = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af");

    final String ppName = "PortPair";
    final String ppDescription = "PortPair";
    final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
    final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";

    final String ppgName = "PortPairGroup";
    final String ppgDescription = "PortPairGroup";
    final List<PortPairId> portPairList = new LinkedList<PortPairId>();

    VirtualPortId id1 = VirtualPortId.portId(ingress);
    VirtualPortId id2 = VirtualPortId.portId("3414");

    DeviceId deviceId = DeviceId.deviceId("of:000000000000001");

    final DriverHandler driverHandler = new MockDriverHandler();

    private List<Port> createPortList() {
        List<Port> portList = Lists.newArrayList();
        long sp1 = 1_000_000;
        ProviderId pid = new ProviderId("of", "foo");
        ChassisId cid = new ChassisId();
        Device device = new DefaultDevice(pid, deviceId, SWITCH, "whitebox", "1.1.x", "3.9.1", "43311-12345", cid);
        Annotations annotations = DefaultAnnotations
                .builder()
                .set(AnnotationKeys.PORT_NAME, "vxlan-0.0.0.0").build();
        Port p1 = new DefaultPort(device, PortNumber.ANY, true, COPPER, sp1, annotations);
        portList.add(p1);
        return portList;
    }

    private PortPair createPortPair(PortPairId ppId) {
        DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
        PortPair portPair = portPairBuilder.setId(ppId).setName(ppName).setTenantId(tenantId)
                .setDescription(ppDescription).setIngress(ingress).setEgress(egress).build();
        return portPair;
    }

    private PortPairGroup createPortPairGroup(PortPairGroupId ppgId) {

        portPairList.clear();
        // Create same two port-pair-group objects.
        portPairList.add(portPairId1);
        portPairList.add(portPairId2);

        DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder();
        PortPairGroup portPairGroup = portPairGroupBuilder.setId(ppgId).setTenantId(tenantId)
                .setName(ppgName).setDescription(ppgDescription).setPortPairs(portPairList).build();

        return portPairGroup;

    }

    private PortChain createPortChain() {

        portPairGroups.clear();
        flowClassifiers.clear();
        // create list of Port Pair Groups.

        portPairGroups.add(portPairGroupId1);
        portPairGroups.add(portPairGroupId2);
        // create list of Flow classifiers.
        flowClassifiers.add(flowClassifierId1);
        flowClassifiers.add(flowClassifierId2);

        DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder();
        final PortChain portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name)
                .setDescription(description).setPortPairGroups(portPairGroups).setFlowClassifiers(flowClassifiers)
                .build();

        return portChain;
    }

    private FlowClassifier createFlowClassifier(FlowClassifierId id) {
        final String name = "FlowClassifier1";
        final String description = "FlowClassifier1";
        final String ethType = "IPv4";
        final String protocol = "tcp";
        final int minSrcPortRange = 5;
        final int maxSrcPortRange = 10;
        final int minDstPortRange = 5;
        final int maxDstPortRange = 10;
        final TenantId tenantId = TenantId.tenantId("1");
        final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
        final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0");
        final VirtualPortId virtualSrcPort = id1;
        final VirtualPortId virtualDstPort = id2;

        DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
        final FlowClassifier flowClassifier = flowClassifierBuilder.setFlowClassifierId(id)
                .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType)
                .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
                .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
                .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();
        return flowClassifier;
    }

    private VirtualPort createVirtualPort(VirtualPortId id) {
        Set<FixedIp> fixedIps;
        Map<String, String> propertyMap;
        Set<AllowedAddressPair> allowedAddressPairs;
        Set<SecurityGroup> securityGroups = Sets.newHashSet();

        String macAddressStr = "fa:12:3e:56:ee:a2";
        String ipAddress = "10.1.1.1";
        String subnet = "1212";
        String hostIdStr = "fa:e2:3e:56:ee:a2";
        String deviceOwner = "james";
        propertyMap = Maps.newHashMap();
        propertyMap.putIfAbsent("deviceOwner", deviceOwner);

        TenantNetworkId networkId = TenantNetworkId.networkId(networkIdStr);
        MacAddress macAddress = MacAddress.valueOf(macAddressStr);
        BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr);
        FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet),
                                          IpAddress.valueOf(ipAddress));
        fixedIps = Sets.newHashSet();
        fixedIps.add(fixedIp);

        allowedAddressPairs = Sets.newHashSet();
        AllowedAddressPair allowedAddressPair = AllowedAddressPair
                .allowedAddressPair(IpAddress.valueOf(ipAddress),
                                    MacAddress.valueOf(macAddressStr));
        allowedAddressPairs.add(allowedAddressPair);

        VirtualPort d1 = new DefaultVirtualPort(id, networkId, true,
                                                propertyMap,
                                                VirtualPort.State.ACTIVE,
                                                macAddress, tenantId, deviceId,
                                                fixedIps, bindingHostId,
                                                allowedAddressPairs,
                                                securityGroups);
        return d1;
    }

    @Test
    public void testInstallFlowClassifier() {

        ApplicationId appId = new DefaultApplicationId(1, "test");
        SfcFlowRuleInstallerImpl flowClassifierInstaller = new SfcFlowRuleInstallerImpl();
        flowClassifierInstaller.virtualPortService = virtualPortService;
        flowClassifierInstaller.vtnRscService = vtnRscService;
        flowClassifierInstaller.portPairService = portPairService;
        flowClassifierInstaller.portPairGroupService = portPairGroupService;
        flowClassifierInstaller.flowClassifierService = flowClassifierService;
        flowClassifierInstaller.driverService = driverService;
        flowClassifierInstaller.deviceService = deviceService;
        flowClassifierInstaller.hostService = hostService;
        flowClassifierInstaller.flowObjectiveService = flowObjectiveService;
        flowClassifierInstaller.appId = appId;

        final PortChain portChain = createPortChain();
        NshServicePathId nshSpiId = NshServicePathId.of(10);

        portPairGroupService.createPortPairGroup(createPortPairGroup(portPairGroupId1));
        portPairGroupService.createPortPairGroup(createPortPairGroup(portPairGroupId2));
        portPairService.createPortPair(createPortPair(portPairId1));
        portPairService.createPortPair(createPortPair(portPairId2));
        FlowClassifier fc1 = createFlowClassifier(flowClassifierId1);
        FlowClassifier fc2 = createFlowClassifier(flowClassifierId2);
        flowClassifierService.createFlowClassifier(fc1);
        flowClassifierService.createFlowClassifier(fc2);

        List<VirtualPort> virtualPortList = Lists.newArrayList();
        virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress)));
        virtualPortService.createPorts(virtualPortList);

        expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes();
        replay(driverService);

        ConnectPoint connectPoint = flowClassifierInstaller.installFlowClassifier(portChain, nshSpiId);

        assertThat(connectPoint, is(HostLocation.NONE));
    }

    @Test
    public void testInstallLoadBalancedFlowRules() {
        ApplicationId appId = new DefaultApplicationId(1, "test");
        SfcFlowRuleInstallerImpl flowRuleInstaller = new SfcFlowRuleInstallerImpl();
        flowRuleInstaller.virtualPortService = virtualPortService;
        flowRuleInstaller.vtnRscService = vtnRscService;
        flowRuleInstaller.portPairService = portPairService;
        flowRuleInstaller.portPairGroupService = portPairGroupService;
        flowRuleInstaller.flowClassifierService = flowClassifierService;
        flowRuleInstaller.driverService = driverService;
        flowRuleInstaller.deviceService = deviceService;
        flowRuleInstaller.hostService = hostService;
        flowRuleInstaller.flowObjectiveService = flowObjectiveService;
        flowRuleInstaller.tenantNetworkService = tenantNetworkService;
        flowRuleInstaller.appId = appId;

        final PortChain portChain = createPortChain();

        final String ppName1 = "PortPair1";
        final String ppDescription1 = "PortPair1";
        final String ingress1 = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
        final String egress1 = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";
        DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
        PortPair portPair1 = portPairBuilder.setId(portPairId1).setName(ppName1).setTenantId(tenantId)
                .setDescription(ppDescription1).setIngress(ingress1).setEgress(egress1).build();

        final String ppName2 = "PortPair2";
        final String ppDescription2 = "PortPair2";
        final String ingress2 = "d5555555-24fc-4fae-af4b-321c5e2eb3d1";
        final String egress2 = "a6666666-4a56-2a6e-cd3a-9dee4e2ec345";
        PortPair portPair2 = portPairBuilder.setId(portPairId2).setName(ppName2).setTenantId(tenantId)
                .setDescription(ppDescription2).setIngress(ingress2).setEgress(egress2).build();

        portPairService.createPortPair(portPair1);
        portPairService.createPortPair(portPair2);

        FlowClassifier fc1 = createFlowClassifier(flowClassifierId1);
        FlowClassifier fc2 = createFlowClassifier(flowClassifierId2);
        flowClassifierService.createFlowClassifier(fc1);
        flowClassifierService.createFlowClassifier(fc2);

        NshServicePathId nshSpiId = NshServicePathId.of(10);
        FiveTuple fiveTuple = DefaultFiveTuple.builder().setIpSrc(IpAddress.valueOf("3.3.3.3"))
                .setIpDst(IpAddress.valueOf("4.4.4.4"))
                .setPortSrc(PortNumber.portNumber(1500))
                .setPortDst(PortNumber.portNumber(2000))
                .setProtocol(IPv4.PROTOCOL_UDP)
                .setTenantId(TenantId.tenantId("bbb"))
                .build();
        LoadBalanceId id = LoadBalanceId.of((byte) 1);

        List<PortPairId> path = Lists.newArrayList();
        path.add(portPairId1);
        path.add(portPairId2);

        List<VirtualPort> virtualPortList = Lists.newArrayList();
        virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress1)));
        virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress1)));
        virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress2)));
        virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress2)));
        virtualPortService.createPorts(virtualPortList);

        portChain.addLoadBalancePath(fiveTuple, id, path);

        String physicalNetworkStr = "1234";
        String segmentationIdStr = "1";
        SegmentationId segmentationID = SegmentationId
                .segmentationId(segmentationIdStr);
        TenantNetworkId networkid1 = TenantNetworkId.networkId(networkIdStr);
        PhysicalNetwork physicalNetwork = PhysicalNetwork
                .physicalNetwork(physicalNetworkStr);
        TenantNetwork p1 = new DefaultTenantNetwork(networkid1, name, false,
                                                    TenantNetwork.State.ACTIVE,
                                                    false, tenantId, false,
                                                    TenantNetwork.Type.LOCAL,
                                                    physicalNetwork,
                                                    segmentationID);
        tenantNetworkService.createNetworks(Collections.singletonList(p1));

        expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes();
        replay(driverService);

        flowRuleInstaller.installLoadBalancedFlowRules(portChain, fiveTuple, nshSpiId);

        ForwardingObjective forObj = ((FlowObjectiveAdapter) flowObjectiveService).forwardingObjective();

        // Check for Selector
        assertThat(forObj.selector().getCriterion(Criterion.Type.IN_PORT), instanceOf(PortCriterion.class));

        // Check for treatment
        List<Instruction> instructions = forObj.treatment().allInstructions();
        for (Instruction instruction : instructions) {
            if (instruction.type() == Instruction.Type.OUTPUT) {
                assertThat(((OutputInstruction) instruction).port(), is(PortNumber.P0));
            }
        }
    }
}
