/*
 * Copyright 2015 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.rest;

import java.util.List;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
import org.onosproject.net.device.DeviceService;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableList;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.onosproject.net.NetTestTools.device;
import static org.onosproject.net.NetTestTools.did;
import static org.onosproject.net.PortNumber.portNumber;

/**
 * Unit tests for devices REST APIs.
 */
public class DevicesResourceTest extends ResourceTest {
    DeviceService mockDeviceService;

    /**
     * Hamcrest matcher to check that an device representation in JSON matches
     * the actual device.
     */
    public static class DeviceJsonMatcher extends TypeSafeMatcher<JsonObject> {
        private final Device device;
        private String reason = "";

        public DeviceJsonMatcher(Device deviceValue) {
            device = deviceValue;
        }

        @Override
        public boolean matchesSafely(JsonObject jsonDevice) {
            // check id
            String jsonId = jsonDevice.get("id").asString();
            if (!jsonId.equals(device.id().toString())) {
                reason = "id " + device.id().toString();
                return false;
            }

            // check type
            String jsonType = jsonDevice.get("type").asString();
            if (!jsonType.equals(device.type().toString())) {
                reason = "appId " + device.type().toString();
                return false;
            }

            // check manufacturer
            String jsonManufacturer = jsonDevice.get("mfr").asString();
            if (!jsonManufacturer.equals(device.manufacturer())) {
                reason = "manufacturer " + device.manufacturer();
                return false;
            }

            // check HW version field
            String jsonHwVersion = jsonDevice.get("hw").asString();
            if (!jsonHwVersion.equals(device.hwVersion())) {
                reason = "hw Version " + device.hwVersion();
                return false;
            }

            // check SW version field
            String jsonSwVersion = jsonDevice.get("sw").asString();
            if (!jsonSwVersion.equals(device.swVersion())) {
                reason = "sw Version " + device.swVersion();
                return false;
            }

            // check serial number field
            String jsonSerialNumber = jsonDevice.get("serial").asString();
            if (!jsonSerialNumber.equals(device.serialNumber())) {
                reason = "serial number " + device.serialNumber();
                return false;
            }

            // check chassis id field
            String jsonChassisId = jsonDevice.get("chassisId").asString();
            if (!jsonChassisId.equals(device.chassisId().toString())) {
                reason = "Chassis id " + device.chassisId().toString();
                return false;
            }

            return true;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText(reason);
        }
    }

    /**
     * Factory to allocate an device matcher.
     *
     * @param device device object we are looking for
     * @return matcher
     */
    private static DeviceJsonMatcher matchesDevice(Device device) {
        return new DeviceJsonMatcher(device);
    }

    /**
     * Hamcrest matcher to check that an device is represented properly in a JSON
     * array of devices.
     */
    private static class DeviceJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
        private final Device device;
        private String reason = "";

        public DeviceJsonArrayMatcher(Device deviceValue) {
            device = deviceValue;
        }

        @Override
        public boolean matchesSafely(JsonArray json) {
            final int minExpectedAttributes = 9;
            final int maxExpectedAttributes = 10;

            boolean deviceFound = false;

            for (int jsonDeviceIndex = 0; jsonDeviceIndex < json.size();
                 jsonDeviceIndex++) {

                JsonObject jsonDevice = json.get(jsonDeviceIndex).asObject();

                if (jsonDevice.names().size() < minExpectedAttributes ||
                    jsonDevice.names().size() > maxExpectedAttributes) {
                    reason = "Found a device with the wrong number of attributes";
                    return false;
                }

                String jsonDeviceId = jsonDevice.get("id").asString();
                if (jsonDeviceId.equals(device.id().toString())) {
                    deviceFound = true;

                    //  We found the correct device, check attribute values
                    assertThat(jsonDevice, matchesDevice(device));
                }
            }
            if (!deviceFound) {
                reason = "Device with id " + device.id().toString() + " not found";
                return false;
            } else {
                return true;
            }
        }

        @Override
        public void describeTo(Description description) {
            description.appendText(reason);
        }
    }

    /**
     * Factory to allocate an device array matcher.
     *
     * @param device device object we are looking for
     * @return matcher
     */
    private static DeviceJsonArrayMatcher hasDevice(Device device) {
        return new DeviceJsonArrayMatcher(device);
    }

    /**
     * Initializes test mocks and environment.
     */
    @Before
    public void setUpMocks() {
        mockDeviceService = createMock(DeviceService.class);

        expect(mockDeviceService.isAvailable(isA(DeviceId.class)))
                .andReturn(true)
                .anyTimes();
        expect(mockDeviceService.getRole(isA(DeviceId.class)))
                .andReturn(MastershipRole.MASTER)
                .anyTimes();

        // Register the services needed for the test
        CodecManager codecService =  new CodecManager();
        codecService.activate();
        ServiceDirectory testDirectory =
                new TestServiceDirectory()
                        .add(DeviceService.class, mockDeviceService)
                        .add(CodecService.class, codecService);

        BaseResource.setServiceDirectory(testDirectory);
    }

    /**
     * Verifies test mocks.
     */
    @After
    public void tearDownMocks() {
        verify(mockDeviceService);
    }

    /**
     * Tests the result of the rest api GET when there are no devices.
     */
    @Test
    public void testDevicesEmptyArray() {
        expect(mockDeviceService.getDevices()).andReturn(ImmutableList.of());
        replay(mockDeviceService);

        WebResource rs = resource();
        String response = rs.path("devices").get(String.class);
        assertThat(response, is("{\"devices\":[]}"));
    }

    /**
     * Tests the result of the rest api GET when there are devices present.
     */
    @Test
    public void testDevices() {
        Device device1 = device("dev1");
        Device device2 = device("dev2");
        Device device3 = device("dev3");

        expect(mockDeviceService.getDevices())
                .andReturn(ImmutableList.of(device1, device2, device3))
                .anyTimes();

        replay(mockDeviceService);

        WebResource rs = resource();
        String response = rs.path("devices").get(String.class);
        assertThat(response, containsString("{\"devices\":["));

        JsonObject result = JsonObject.readFrom(response);
        assertThat(result, notNullValue());

        assertThat(result.names(), hasSize(1));
        assertThat(result.names().get(0), is("devices"));

        JsonArray jsonDevices = result.get("devices").asArray();
        assertThat(jsonDevices, notNullValue());
        assertThat(jsonDevices.size(), is(3));

        assertThat(jsonDevices, hasDevice(device1));
        assertThat(jsonDevices, hasDevice(device2));
        assertThat(jsonDevices, hasDevice(device3));
    }

    /**
     * Tests the result of a rest api GET for a single device.
     */
    @Test
    public void testDevicesSingle() {

        String deviceIdString = "testdevice";
        DeviceId deviceId = did(deviceIdString);
        Device device = device(deviceIdString);

        expect(mockDeviceService.getDevice(deviceId))
                .andReturn(device)
                .once();
        replay(mockDeviceService);

        WebResource rs = resource();
        String response = rs.path("devices/" + deviceId).get(String.class);
        JsonObject result = JsonObject.readFrom(response);
        assertThat(result, matchesDevice(device));
    }

    /**
     * Tests the result of a rest api GET for the ports of a single device.
     */
    @Test
    public void testDeviceAndPorts() {

        String deviceIdString = "testdevice";
        DeviceId deviceId = did(deviceIdString);
        Device device = device(deviceIdString);

        Port port1 = new DefaultPort(device, portNumber(1), true);
        Port port2 = new DefaultPort(device, portNumber(2), true);
        Port port3 = new DefaultPort(device, portNumber(3), true);
        List<Port> ports = ImmutableList.of(port1, port2, port3);

        expect(mockDeviceService.getDevice(deviceId))
                .andReturn(device)
                .once();

        expect(mockDeviceService.getPorts(deviceId))
                .andReturn(ports)
                .once();
        replay(mockDeviceService);

        WebResource rs = resource();
        String response =
                rs.path("devices/" + deviceId + "/ports")
                    .get(String.class);
        JsonObject result = JsonObject.readFrom(response);
        assertThat(result, matchesDevice(device));

        JsonArray jsonPorts = result.get("ports").asArray();
        assertThat(jsonPorts.size(), is(3));
        for (int portIndex = 0; portIndex < jsonPorts.size(); portIndex++) {
            JsonObject jsonPort = jsonPorts.get(portIndex).asObject();

            assertThat(jsonPort.get("port").asString(),
                       is(Integer.toString(portIndex + 1)));
            assertThat(jsonPort.get("isEnabled").asBoolean(),
                       is(true));
            assertThat(jsonPort.get("type").asString(),
                       equalTo("copper"));
            assertThat(jsonPort.get("portSpeed").asLong(),
                    is(1000L));
        }
    }

    /**
     * Tests that a fetch of a non-existent device object throws an exception.
     */
    @Test
    public void testBadGet() {

        expect(mockDeviceService.getDevice(isA(DeviceId.class)))
                .andReturn(null)
                .anyTimes();
        replay(mockDeviceService);

        WebResource rs = resource();
        try {
            rs.path("devices/0").get(String.class);
            fail("Fetch of non-existent device did not throw an exception");
        } catch (UniformInterfaceException ex) {
            assertThat(ex.getMessage(),
                    containsString("returned a response status of"));
        }
    }
}
