/*
 * Copyright 2019-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.segmentrouting.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.basics.BasicDeviceConfig;
import org.onosproject.net.config.basics.BasicHostConfig;
import org.onosproject.net.config.basics.InterfaceConfig;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.net.neighbour.NeighbourResolutionService;
import org.onosproject.segmentrouting.DeviceConfiguration;
import org.onosproject.segmentrouting.SegmentRoutingManager;

import java.io.InputStream;
import java.util.List;
import java.util.Set;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.*;

public class DeviceConfigurationTest {
    private static final DeviceId DEV1 = DeviceId.deviceId("of:1");
    private static final String CONFIG_KEY = "segmentrouting";
    private static final PortNumber PORT1 = PortNumber.portNumber(1);
    private static final PortNumber PORT2 = PortNumber.portNumber(2);
    private static final ConnectPoint CP1 = new ConnectPoint(DEV1, PORT1);
    private static final ConnectPoint CP2 = new ConnectPoint(DEV1, PORT2);
    private static final MacAddress MAC1 = MacAddress.valueOf("00:11:22:33:44:55");
    private static final MacAddress ROUTER_MAC = MacAddress.valueOf("00:00:00:00:01:80");
    private static final HostId ROUTER_HOST = HostId.hostId(ROUTER_MAC, VlanId.NONE);
    private static final VlanId VLAN1 = VlanId.vlanId((short) 10);
    private static final VlanId VLAN2 = VlanId.vlanId((short) 20);
    private static final IpPrefix PREFIX1 = IpPrefix.valueOf("10.0.1.254/24");
    private static final IpPrefix PREFIX2 = IpPrefix.valueOf("10.0.2.254/24");
    private static final IpPrefix ROUTE1 = IpPrefix.valueOf("20.0.1.254/24");
    private static final InterfaceIpAddress INTF1_IP = new InterfaceIpAddress(PREFIX1.address(), PREFIX1);
    private static final InterfaceIpAddress INTF2_IP = new InterfaceIpAddress(PREFIX2.address(), PREFIX2);
    private static final List<InterfaceIpAddress> IP_LIST1 = Lists.newArrayList(INTF1_IP);
    private static final List<InterfaceIpAddress> IP_LIST2 = Lists.newArrayList(INTF2_IP);
    private static final Interface INTF1 = new Interface("mock-intf1", CP1, IP_LIST1, MAC1,
            null, VLAN1, null, null);
    private static final Interface INTF2 = new Interface("mock-intf2", CP2, IP_LIST2, MAC1,
            null, VLAN2, null, null);
    private static final Set<Interface> INTERFACES = Sets.newHashSet(INTF1, INTF2);

    private DeviceConfiguration devConfig;

    private NetworkConfigRegistry networkConfigService;

    @Before
    public void setUp() throws Exception {
        InterfaceService interfaceService;
        networkConfigService = null;
        NeighbourResolutionService neighbourResolutionService;
        SegmentRoutingManager srManager;

        // Mock device netcfg
        InputStream jsonStream = SegmentRoutingDeviceConfigTest.class.getResourceAsStream("/device.json");
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(jsonStream);
        SegmentRoutingDeviceConfig srDevConfig = new SegmentRoutingDeviceConfig();
        srDevConfig.init(DEV1, CONFIG_KEY, jsonNode, mapper, config -> { });
        BasicDeviceConfig basicDeviceConfig = new BasicDeviceConfig();
        basicDeviceConfig.init(DEV1, DEV1.toString(), JsonNodeFactory.instance.objectNode(), mapper, config -> { });

        // Mock interface netcfg
        jsonStream = InterfaceConfig.class.getResourceAsStream("/interface1.json");
        jsonNode = mapper.readTree(jsonStream);
        InterfaceConfig interfaceConfig1 = new InterfaceConfig();
        interfaceConfig1.init(CP1, CONFIG_KEY, jsonNode, mapper, config -> { });

        jsonStream = InterfaceConfig.class.getResourceAsStream("/interface2.json");
        jsonNode = mapper.readTree(jsonStream);
        InterfaceConfig interfaceConfig2 = new InterfaceConfig();
        interfaceConfig2.init(CP1, CONFIG_KEY, jsonNode, mapper, config -> { });

        jsonStream = BasicHostConfig.class.getResourceAsStream("/host1.json");
        jsonNode = mapper.readTree(jsonStream);
        BasicHostConfig hostConfig1 = new BasicHostConfig();
        hostConfig1.init(ROUTER_HOST, "basic", jsonNode, mapper, config -> { });

        networkConfigService = createMock(NetworkConfigRegistry.class);
        expect(networkConfigService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class))
                .andReturn(Sets.newHashSet(DEV1)).anyTimes();
        expect(networkConfigService.getConfig(DEV1, SegmentRoutingDeviceConfig.class))
                .andReturn(srDevConfig).anyTimes();
        expect(networkConfigService.addConfig(DEV1, BasicDeviceConfig.class))
                .andReturn(basicDeviceConfig).anyTimes();
        expect(networkConfigService.getConfig(DEV1, BasicDeviceConfig.class))
                .andReturn(basicDeviceConfig).anyTimes();
        expect(networkConfigService.getSubjects(ConnectPoint.class, InterfaceConfig.class))
                .andReturn(Sets.newHashSet(CP1, CP2)).anyTimes();
        expect(networkConfigService.getConfig(CP1, InterfaceConfig.class)).andReturn(interfaceConfig1).anyTimes();
        expect(networkConfigService.getConfig(CP2, InterfaceConfig.class)).andReturn(interfaceConfig2).anyTimes();
        expect(networkConfigService.applyConfig(eq(CP1), eq(InterfaceConfig.class), anyObject()))
                .andReturn(interfaceConfig1).anyTimes();
        expect(networkConfigService.applyConfig(eq(CP2), eq(InterfaceConfig.class), anyObject()))
                .andReturn(interfaceConfig2).anyTimes();
        expect(networkConfigService.getConfig(null, SegmentRoutingAppConfig.class)).andReturn(null).anyTimes();
        expect(networkConfigService.getConfig(ROUTER_HOST, BasicHostConfig.class)).andReturn(hostConfig1).anyTimes();
        expect(networkConfigService.applyConfig(eq(ROUTER_HOST), eq(BasicHostConfig.class), anyObject()))
                .andReturn(hostConfig1).anyTimes();
        replay(networkConfigService);

        interfaceService = createMock(InterfaceService.class);
        expect(interfaceService.getInterfaces()).andReturn(INTERFACES).anyTimes();
        expect(interfaceService.getInterfacesByPort(CP1)).andReturn(Sets.newHashSet(INTF1)).anyTimes();
        expect(interfaceService.getInterfacesByPort(CP2)).andReturn(Sets.newHashSet(INTF2)).anyTimes();
        replay(interfaceService);

        neighbourResolutionService = createMock(NeighbourResolutionService.class);
        neighbourResolutionService.registerNeighbourHandler(anyObject(ConnectPoint.class), anyObject(), anyObject());
        expectLastCall().anyTimes();
        replay(neighbourResolutionService);

        srManager = new SegmentRoutingManager();
        srManager.interfaceService = interfaceService;
        srManager.cfgService = networkConfigService;
        srManager.neighbourResolutionService = neighbourResolutionService;

        devConfig = new DeviceConfiguration(srManager);
        devConfig.addSubnet(CP2, ROUTE1);
    }

    @Test
    public void getConfiguredSubnets() {
        Set<IpPrefix> expect = Sets.newHashSet(PREFIX1, PREFIX2);
        assertEquals(expect, devConfig.getConfiguredSubnets(DEV1));
    }

    @Test
    public void getSubnets() {
        Set<IpPrefix> expect = Sets.newHashSet(PREFIX1, PREFIX2, ROUTE1);
        assertEquals(expect, devConfig.getSubnets(DEV1));
    }

    @Test
    public void getPortSubnets() {
        assertEquals(Sets.newHashSet(PREFIX1), devConfig.getPortSubnets(DEV1, PORT1));
        assertEquals(Sets.newHashSet(PREFIX2), devConfig.getPortSubnets(DEV1, PORT2));
    }

    @Test
    public void inSameSubnet() {
        assertTrue(devConfig.inSameSubnet(DEV1, PREFIX1.address()));
        assertTrue(devConfig.inSameSubnet(DEV1, PREFIX2.address()));
        assertFalse(devConfig.inSameSubnet(DEV1, ROUTE1.address()));
    }
}