package org.onosproject.codec.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import java.util.stream.IntStream;

import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.VirtualHost;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.NetTestTools;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isOneOf;
import static org.hamcrest.Matchers.notNullValue;

/**
 * Tests VirtualHostCodec class.
 */

public class VirtualHostCodecTest {

    private static final String TEST_IP1 = "1.1.1.1";
    private static final String TEST_IP2 = "2.2.2.2";
    private static final String TEST_HOST_ID = "12:34:56:78:90:11/1";
    private static final String TEST_MAC_ADDRESS = "11:11:22:22:33:33";
    private static final long TEST_NETWORK_ID = 44L;
    private static final short TEST_VLAN_ID = (short) 12;
    private static final ConnectPoint CONNECT_POINT =
            NetTestTools.connectPoint("d1", 1);

    @Test
    public void testEncode() {
        MockCodecContext context = new MockCodecContext();
        NetworkId networkId = NetworkId.networkId(TEST_NETWORK_ID);
        HostId id = NetTestTools.hid(TEST_HOST_ID);
        MacAddress mac = MacAddress.valueOf(TEST_MAC_ADDRESS);
        VlanId vlan = VlanId.vlanId(TEST_VLAN_ID);
        HostLocation location =
                new HostLocation(CONNECT_POINT, 0L);
        Set<IpAddress> ips = ImmutableSet.of(IpAddress.valueOf(TEST_IP1),
                                             IpAddress.valueOf(TEST_IP2));
        VirtualHost host =
                new DefaultVirtualHost(networkId, id, mac, vlan, location, ips);
        JsonCodec<VirtualHost> codec = context.codec(VirtualHost.class);
        ObjectNode node = codec.encode(host, context);

        System.out.println(node.toString());

        assertThat(node.get(VirtualHostCodec.NETWORK_ID).asLong(),
                   is(TEST_NETWORK_ID));
        assertThat(node.get(VirtualHostCodec.HOST_ID).asText(),
                   is(TEST_HOST_ID));
        assertThat(node.get(VirtualHostCodec.MAC_ADDRESS).asText(),
                   is(TEST_MAC_ADDRESS));
        assertThat(node.get(VirtualHostCodec.VLAN).asInt(),
                   is((int) TEST_VLAN_ID));
        assertThat(node.get(VirtualHostCodec.HOST_LOCATION).get("elementId").asText(),
                   is(location.deviceId().toString()));
        assertThat(node.get(VirtualHostCodec.HOST_LOCATION).get("port").asLong(),
                   is(location.port().toLong()));

        JsonNode jsonIps = node.get(VirtualHostCodec.IP_ADDRESSES);
        assertThat(jsonIps, notNullValue());
        assertThat(jsonIps.isArray(), is(true));
        assertThat(jsonIps.size(), is(ips.size()));

        IntStream.of(0, 1).forEach(index ->
            assertThat(jsonIps.get(index).asText(),
                       isOneOf(TEST_IP1, TEST_IP2)));
    }

    @Test
    public void testDecode() throws IOException {
        MockCodecContext context = new MockCodecContext();
        InputStream jsonStream =
                VirtualHostCodecTest.class.getResourceAsStream("VirtualHost.json");
        JsonNode json = context.mapper().readTree(jsonStream);
        assertThat(json, notNullValue());
        JsonCodec<VirtualHost> codec = context.codec(VirtualHost.class);
        VirtualHost virtualHost = codec.decode((ObjectNode) json, context);
        assertThat(virtualHost, notNullValue());

        assertThat(virtualHost.networkId().id(),
                   is(TEST_NETWORK_ID));
        assertThat(virtualHost.id().toString(),
                   is(NetTestTools.hid(TEST_MAC_ADDRESS + "/12").toString()));
        assertThat(virtualHost.mac().toString(),
                   is(TEST_MAC_ADDRESS));
        assertThat(virtualHost.vlan().id(),
                   is((short) TEST_VLAN_ID));
        assertThat(virtualHost.location().deviceId(),
                   is(CONNECT_POINT.deviceId()));
        assertThat(virtualHost.location().port().toLong(),
                   is(CONNECT_POINT.port().toLong()));


        assertThat(virtualHost.ipAddresses().contains(IpAddress.valueOf(TEST_IP1)),
                   is(true));
        assertThat(virtualHost.ipAddresses().contains(IpAddress.valueOf(TEST_IP2)),
                   is(true));
    }
}
