/*
 * 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.k8snode.api;

import com.google.common.testing.EqualsTester;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onosproject.k8snode.api.K8sNode.Type;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.ProviderId;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertSame;
import static org.onosproject.k8snode.api.K8sNode.Type.MINION;
import static org.onosproject.k8snode.api.K8sNodeState.COMPLETE;
import static org.onosproject.k8snode.api.K8sNodeState.DEVICE_CREATED;
import static org.onosproject.k8snode.api.K8sNodeState.INIT;
import static org.onosproject.net.Device.Type.SWITCH;

/**
 * Unit test for DefaultK8sNode.
 */
public final class DefaultK8sNodeTest {

    private static final IpAddress TEST_IP = IpAddress.valueOf("10.100.0.3");

    private static final String HOSTNAME_1 = "hostname_1";
    private static final String HOSTNAME_2 = "hostname_2";
    private static final Device DEVICE_1 = createDevice(1);
    private static final Device DEVICE_2 = createDevice(2);

    private static final IpAddress MANAGEMENT_IP = IpAddress.valueOf("10.10.10.10");
    private static final IpAddress DATA_IP = IpAddress.valueOf("20.20.20.20");

    private static final String BRIDGE_INTF_1 = "eth1";
    private static final String BRIDGE_INTF_2 = "eth2";

    private static final IpAddress EXT_BRIDGE_IP_1 = IpAddress.valueOf("10.10.10.5");
    private static final IpAddress EXT_BRIDGE_IP_2 = IpAddress.valueOf("20.20.20.5");

    private static final IpAddress EXT_GATEWAY_IP_1 = IpAddress.valueOf("10.10.10.1");
    private static final IpAddress EXT_GATEWAY_IP_2 = IpAddress.valueOf("20.20.20.1");

    private static final String POD_CIDR_1 = "10.10.0.0/24";
    private static final String POD_CIDR_2 = "20.20.0.0/24";

    private K8sNode refNode;

    private static final K8sNode K8S_NODE_1 = createNode(
            HOSTNAME_1,
            MINION,
            DEVICE_1,
            DEVICE_1,
            DEVICE_1,
            BRIDGE_INTF_1,
            TEST_IP,
            INIT,
            EXT_BRIDGE_IP_1,
            EXT_GATEWAY_IP_1,
            POD_CIDR_1);
    private static final K8sNode K8S_NODE_2 = createNode(
            HOSTNAME_1,
            MINION,
            DEVICE_1,
            DEVICE_1,
            DEVICE_1,
            BRIDGE_INTF_1,
            TEST_IP,
            INIT,
            EXT_BRIDGE_IP_1,
            EXT_GATEWAY_IP_1,
            POD_CIDR_1);
    private static final K8sNode K8S_NODE_3 = createNode(
            HOSTNAME_2,
            MINION,
            DEVICE_2,
            DEVICE_2,
            DEVICE_2,
            BRIDGE_INTF_2,
            TEST_IP,
            INIT,
            EXT_BRIDGE_IP_2,
            EXT_GATEWAY_IP_2,
            POD_CIDR_2);

    /**
     * Initial setup for this unit test.
     */
    @Before
    public void setUp() {
        refNode = DefaultK8sNode.builder()
                .hostname(HOSTNAME_1)
                .type(MINION)
                .managementIp(MANAGEMENT_IP)
                .dataIp(DATA_IP)
                .intgBridge(DEVICE_1.id())
                .extBridge(DEVICE_1.id())
                .localBridge(DEVICE_1.id())
                .extIntf(BRIDGE_INTF_1)
                .state(COMPLETE)
                .extBridgeIp(EXT_BRIDGE_IP_1)
                .extGatewayIp(EXT_GATEWAY_IP_1)
                .podCidr(POD_CIDR_1)
                .build();
    }

    /**
     * Checks equals method works as expected.
     */
    @Test
    public void testEquality() {
        new EqualsTester().addEqualityGroup(K8S_NODE_1, K8S_NODE_2)
                .addEqualityGroup(K8S_NODE_3)
                .testEquals();
    }

    /**
     * Test object construction.
     */
    @Test
    public void testConstruction() {
        checkCommonProperties(refNode);
        assertSame(refNode.state(), COMPLETE);
        assertEquals(refNode.intgBridge(), DEVICE_1.id());
        assertEquals(refNode.extBridge(), DEVICE_1.id());
        assertEquals(refNode.localBridge(), DEVICE_1.id());
    }

    /**
     * Checks the functionality of update state method.
     */
    @Test
    public void testUpdateState() {
        K8sNode updatedNode = refNode.updateState(DEVICE_CREATED);

        checkCommonProperties(updatedNode);
        assertSame(updatedNode.state(), DEVICE_CREATED);
    }

    /**
     * Checks the functionality of from method.
     */
    @Test
    public void testFrom() {
        K8sNode updatedNode = DefaultK8sNode.from(refNode).build();

        assertEquals(updatedNode, refNode);
    }

    /**
     * Checks building a node without hostname fails with proper exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testBuildWithoutHostname() {
        DefaultK8sNode.builder()
                .type(MINION)
                .intgBridge(DEVICE_1.id())
                .extBridge(DEVICE_1.id())
                .localBridge(DEVICE_1.id())
                .extIntf(BRIDGE_INTF_1)
                .managementIp(TEST_IP)
                .dataIp(TEST_IP)
                .state(INIT)
                .extBridgeIp(EXT_BRIDGE_IP_1)
                .extGatewayIp(EXT_GATEWAY_IP_1)
                .podCidr(POD_CIDR_1)
                .build();
    }

    /**
     * Checks building a node without type fails with proper exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testBuildWithoutType() {
        DefaultK8sNode.builder()
                .hostname(HOSTNAME_1)
                .intgBridge(DEVICE_1.id())
                .extBridge(DEVICE_1.id())
                .localBridge(DEVICE_1.id())
                .extIntf(BRIDGE_INTF_1)
                .managementIp(TEST_IP)
                .dataIp(TEST_IP)
                .state(INIT)
                .extBridgeIp(EXT_BRIDGE_IP_1)
                .extGatewayIp(EXT_GATEWAY_IP_1)
                .podCidr(POD_CIDR_1)
                .build();
    }

    /**
     * Checks building a node without management IP address fails with
     * proper exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testBuildWithoutManagementIp() {
        DefaultK8sNode.builder()
                .hostname(HOSTNAME_1)
                .type(MINION)
                .intgBridge(DEVICE_1.id())
                .extBridge(DEVICE_1.id())
                .localBridge(DEVICE_1.id())
                .extIntf(BRIDGE_INTF_1)
                .dataIp(TEST_IP)
                .state(INIT)
                .extBridgeIp(EXT_BRIDGE_IP_1)
                .extGatewayIp(EXT_GATEWAY_IP_1)
                .podCidr(POD_CIDR_1)
                .build();
    }

    private void checkCommonProperties(K8sNode node) {
        assertEquals(node.hostname(), HOSTNAME_1);
        assertEquals(node.type(), MINION);
        assertEquals(node.managementIp(), MANAGEMENT_IP);
        assertEquals(node.dataIp(), DATA_IP);
    }

    private static Device createDevice(long devIdNum) {
        return new DefaultDevice(new ProviderId("of", "foo"),
                DeviceId.deviceId(String.format("of:%016d", devIdNum)),
                SWITCH,
                "manufacturer",
                "hwVersion",
                "swVersion",
                "serialNumber",
                new ChassisId(1));
    }

    private static K8sNode createNode(String hostname, Type type,
                                      Device intgBridge, Device extBridge,
                                      Device localBridge, String bridgeIntf,
                                      IpAddress ipAddr, K8sNodeState state,
                                      IpAddress extBridgeIp, IpAddress extGatewayIp,
                                      String podCidr) {
        return DefaultK8sNode.builder()
                .hostname(hostname)
                .type(type)
                .intgBridge(intgBridge.id())
                .extBridge(extBridge.id())
                .localBridge(localBridge.id())
                .extIntf(bridgeIntf)
                .managementIp(ipAddr)
                .dataIp(ipAddr)
                .state(state)
                .extBridgeIp(extBridgeIp)
                .extGatewayIp(extGatewayIp)
                .podCidr(podCidr)
                .build();
    }
}
