/*
 * Copyright 2018-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.openstacknode.codec;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableList;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.core.CoreService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.openstacknode.api.DefaultOpenstackAuth;
import org.onosproject.openstacknode.api.DefaultOpenstackNode;
import org.onosproject.openstacknode.api.DpdkConfig;
import org.onosproject.openstacknode.api.DpdkInterface;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackAuth;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackPhyInterface;
import org.onosproject.openstacknode.api.OpenstackSshAuth;
import org.onosproject.openstacknode.impl.DefaultDpdkConfig;
import org.onosproject.openstacknode.impl.DefaultDpdkInterface;
import org.onosproject.openstacknode.impl.DefaultOpenstackPhyInterface;
import org.onosproject.openstacknode.impl.DefaultOpenstackSshAuth;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.openstacknode.codec.OpenstackNodeJsonMatcher.matchesOpenstackNode;

/**
 * Unit tests for OpenstackNode codec.
 */
public class OpenstackNodeCodecTest {
    MockCodecContext context;
    JsonCodec<OpenstackNode> openstackNodeCodec;
    JsonCodec<OpenstackPhyInterface> openstackPhyIntfJsonCodec;
    JsonCodec<ControllerInfo> openstackControllerJsonCodec;
    JsonCodec<OpenstackAuth> openstackAuthJsonCodec;
    JsonCodec<OpenstackSshAuth> openstackSshAuthJsonCodec;
    JsonCodec<DpdkConfig> dpdkConfigJsonCodec;
    JsonCodec<DpdkInterface> dpdkInterfaceJsonCodec;

    final CoreService mockCoreService = createMock(CoreService.class);
    private static final String REST_APP_ID = "org.onosproject.rest";

    @Before
    public void setUp() {
        context = new MockCodecContext();
        openstackNodeCodec = new OpenstackNodeCodec();
        openstackPhyIntfJsonCodec = new OpenstackPhyInterfaceCodec();
        openstackControllerJsonCodec = new OpenstackControllerCodec();
        openstackAuthJsonCodec = new OpenstackAuthCodec();
        openstackSshAuthJsonCodec = new OpenstackSshAuthCodec();
        dpdkConfigJsonCodec = new DpdkConfigCodec();
        dpdkInterfaceJsonCodec = new DpdkInterfaceCodec();

        assertThat(openstackNodeCodec, notNullValue());
        assertThat(openstackPhyIntfJsonCodec, notNullValue());
        assertThat(openstackControllerJsonCodec, notNullValue());
        assertThat(openstackAuthJsonCodec, notNullValue());
        assertThat(openstackSshAuthJsonCodec, notNullValue());
        assertThat(dpdkConfigJsonCodec, notNullValue());
        assertThat(dpdkInterfaceJsonCodec, notNullValue());

        expect(mockCoreService.registerApplication(REST_APP_ID))
                .andReturn(APP_ID).anyTimes();
        replay(mockCoreService);
        context.registerService(CoreService.class, mockCoreService);
    }

    /**
     * Tests the openstack compute node encoding.
     */
    @Test
    public void testOpenstackComputeNodeEncode() {

        OpenstackPhyInterface phyIntf1 = DefaultOpenstackPhyInterface.builder()
                                .network("mgmtnetwork")
                                .intf("eth3")
                                .build();
        OpenstackPhyInterface phyIntf2 = DefaultOpenstackPhyInterface.builder()
                                .network("oamnetwork")
                                .intf("eth4")
                                .build();

        OpenstackSshAuth sshAuth = DefaultOpenstackSshAuth.builder()
                .id("sdn")
                .password("sdn")
                .build();

        ControllerInfo controller1 =
                new ControllerInfo(IpAddress.valueOf("10.10.10.2"), 6653, "tcp");
        ControllerInfo controller2 =
                new ControllerInfo(IpAddress.valueOf("10.10.10.3"), 6663, "tcp");

        OpenstackNode node = DefaultOpenstackNode.builder()
                                .hostname("compute")
                                .type(OpenstackNode.NodeType.COMPUTE)
                                .state(NodeState.INIT)
                                .managementIp(IpAddress.valueOf("10.10.10.1"))
                                .intgBridge(DeviceId.deviceId("br-int"))
                                .vlanIntf("vlan")
                                .dataIp(IpAddress.valueOf("20.20.20.2"))
                                .phyIntfs(ImmutableList.of(phyIntf1, phyIntf2))
                                .controllers(ImmutableList.of(controller1, controller2))
                                .sshAuthInfo(sshAuth)
                                .build();

        ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
        assertThat(nodeJson, matchesOpenstackNode(node));
    }

    /**
     * Tests the openstack compute node decoding.
     *
     * @throws IOException io exception
     */
    @Test
    public void testOpenstackComputeNodeDecode() throws IOException {
        OpenstackNode node = getOpenstackNode("OpenstackComputeNode.json");

        assertThat(node.hostname(), is("compute-01"));
        assertThat(node.type().name(), is("COMPUTE"));
        assertThat(node.managementIp().toString(), is("172.16.130.4"));
        assertThat(node.dataIp().toString(), is("172.16.130.4"));
        assertThat(node.intgBridge().toString(), is("of:00000000000000a1"));
        assertThat(node.vlanIntf(), is("eth2"));
        assertThat(node.phyIntfs().size(), is(2));
        assertThat(node.controllers().size(), is(2));
        assertThat(node.sshAuthInfo().id(), is("sdn"));
        assertThat(node.sshAuthInfo().password(), is("sdn"));
        assertThat(node.datapathType(), is(DpdkConfig.DatapathType.NORMAL));


        node.phyIntfs().forEach(intf -> {
            if (intf.network().equals("mgmtnetwork")) {
                assertThat(intf.intf(), is("eth3"));
            }
            if (intf.network().equals("oamnetwork")) {
                assertThat(intf.intf(), is("eth4"));
            }
        });

        node.controllers().forEach(ctrl -> {
            if (ctrl.ip().toString().equals("10.10.10.2")) {
                assertThat(ctrl.port(), is(6653));
            }
            if (ctrl.ip().toString().equals("10.10.10.3")) {
                assertThat(ctrl.port(), is(6663));
            }
        });
    }

    /**
     * Tests the openstack compute node encoding with dpdk config.
     */
    @Test
    public void testOpenstackDpdkComputeNodeEncode() {
        DpdkInterface dpdkInterface1 = DefaultDpdkInterface.builder()
                .deviceName("br-int")
                .intf("dpdk0")
                .mtu(Long.valueOf(1600))
                .pciAddress("0000:85:00.0")
                .type(DpdkInterface.Type.DPDK)
                .build();

        DpdkInterface dpdkInterface2 = DefaultDpdkInterface.builder()
                .deviceName("br-tun")
                .intf("dpdk1")
                .pciAddress("0000:85:00.1")
                .type(DpdkInterface.Type.DPDK)
                .build();

        Collection<DpdkInterface> dpdkInterfaceCollection = new ArrayList<>();
        dpdkInterfaceCollection.add(dpdkInterface1);
        dpdkInterfaceCollection.add(dpdkInterface2);


        DpdkConfig dpdkConfig = DefaultDpdkConfig.builder()
                .datapathType(DpdkConfig.DatapathType.NETDEV)
                .dpdkIntfs(dpdkInterfaceCollection)
                .build();

        OpenstackNode node = DefaultOpenstackNode.builder()
                .hostname("compute")
                .type(OpenstackNode.NodeType.COMPUTE)
                .state(NodeState.INIT)
                .managementIp(IpAddress.valueOf("10.10.10.1"))
                .intgBridge(DeviceId.deviceId("br-int"))
                .vlanIntf("vlan")
                .dataIp(IpAddress.valueOf("20.20.20.2"))
                .dpdkConfig(dpdkConfig)
                .build();

        ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
        assertThat(nodeJson, matchesOpenstackNode(node));
    }

    /**
     * Tests the openstack compute node decoding with dpdk config.
     *
     * @throws IOException io exception
     */
    @Test
    public void testOpenstackDpdkComputeNodeDecode() throws IOException {
        OpenstackNode node = getOpenstackNode("OpenstackDpdkComputeNode.json");

        assertEquals(node.datapathType(), DpdkConfig.DatapathType.NETDEV);
        assertEquals(node.socketDir(), "/var/lib/libvirt/qemu");
        assertEquals(node.dpdkConfig().dpdkIntfs().size(), 2);
    }

    /**
     * Tests the openstack controller node encoding.
     */
    @Test
    public void testOpenstackControllerNodeEncode() {
        OpenstackAuth auth = DefaultOpenstackAuth.builder()
                .version("v2.0")
                .protocol(OpenstackAuth.Protocol.HTTP)
                .project("admin")
                .username("admin")
                .password("nova")
                .perspective(OpenstackAuth.Perspective.PUBLIC)
                .build();

        OpenstackNode node = DefaultOpenstackNode.builder()
                .hostname("controller")
                .type(OpenstackNode.NodeType.CONTROLLER)
                .state(NodeState.INIT)
                .managementIp(IpAddress.valueOf("172.16.130.10"))
                .endpoint("keystone-end-point-url")
                .authentication(auth)
                .build();

        ObjectNode nodeJson = openstackNodeCodec.encode(node, context);
        assertThat(nodeJson, matchesOpenstackNode(node));
    }

    /**
     * Tests the openstack controller node decoding.
     */
    @Test
    public void testOpenstackControllerNodeDecode() throws IOException {
        OpenstackNode node = getOpenstackNode("OpenstackControllerNode.json");

        assertThat(node.hostname(), is("controller"));
        assertThat(node.type().name(), is("CONTROLLER"));
        assertThat(node.managementIp().toString(), is("172.16.130.10"));
        assertThat(node.endpoint(), is("keystone-end-point-url"));

        OpenstackAuth auth = node.authentication();

        assertThat(auth.version(), is("v2.0"));
        assertThat(auth.protocol(), is(OpenstackAuth.Protocol.HTTP));
        assertThat(auth.username(), is("admin"));
        assertThat(auth.password(), is("nova"));
        assertThat(auth.project(), is("admin"));
        assertThat(auth.perspective(), is(OpenstackAuth.Perspective.PUBLIC));
    }

    /**
     * Reads in an openstack node from the given resource and decodes it.
     *
     * @param resourceName resource to use to read the JSON for the rule
     * @return decoded openstack node
     * @throws IOException if processing the resource fails
     */
    private OpenstackNode getOpenstackNode(String resourceName) throws IOException {
        InputStream jsonStream = OpenstackNodeCodecTest.class.getResourceAsStream(resourceName);
        JsonNode json = context.mapper().readTree(jsonStream);
        MatcherAssert.assertThat(json, notNullValue());
        OpenstackNode node = openstackNodeCodec.decode((ObjectNode) json, context);
        assertThat(node, notNullValue());
        return node;
    }

    /**
     * Mock codec context for use in codec unit tests.
     */
    private class MockCodecContext implements CodecContext {
        private final ObjectMapper mapper = new ObjectMapper();
        private final CodecManager manager = new CodecManager();
        private final Map<Class<?>, Object> services = new HashMap<>();

        /**
         * Constructs a new mock codec context.
         */
        public MockCodecContext() {
            manager.activate();
        }

        @Override
        public ObjectMapper mapper() {
            return mapper;
        }

        @Override
        @SuppressWarnings("unchecked")
        public <T> JsonCodec<T> codec(Class<T> entityClass) {
            if (entityClass == OpenstackPhyInterface.class) {
                return (JsonCodec<T>) openstackPhyIntfJsonCodec;
            }
            if (entityClass == ControllerInfo.class) {
                return (JsonCodec<T>) openstackControllerJsonCodec;
            }
            if (entityClass == OpenstackAuth.class) {
                return (JsonCodec<T>) openstackAuthJsonCodec;
            }
            if (entityClass == OpenstackSshAuth.class) {
                return (JsonCodec<T>) openstackSshAuthJsonCodec;
            }
            if (entityClass == DpdkConfig.class) {
                return (JsonCodec<T>) dpdkConfigJsonCodec;
            }
            if (entityClass == DpdkInterface.class) {
                return (JsonCodec<T>) dpdkInterfaceJsonCodec;
            }
            return manager.getCodec(entityClass);
        }

        @SuppressWarnings("unchecked")
        @Override
        public <T> T getService(Class<T> serviceClass) {
            return (T) services.get(serviceClass);
        }

        // for registering mock services
        public <T> void registerService(Class<T> serviceClass, T impl) {
            services.put(serviceClass, impl);
        }
    }
}
