/*
 * Copyright 2016 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.resources;

import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import org.hamcrest.Description;
import org.hamcrest.Matchers;
import org.hamcrest.TypeSafeMatcher;
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.key.DeviceKey;
import org.onosproject.net.key.DeviceKeyAdminService;
import org.onosproject.net.key.DeviceKeyId;
import org.onosproject.net.key.DeviceKeyService;

import javax.ws.rs.BadRequestException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.HashSet;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

/**
 * Unit tests for device key REST APIs.
 */
public class DeviceKeyWebResourceTest extends ResourceTest {

    final DeviceKeyService mockDeviceKeyService = createMock(DeviceKeyService.class);
    final DeviceKeyAdminService mockDeviceKeyAdminService = createMock(DeviceKeyAdminService.class);

    final HashSet<DeviceKey> deviceKeySet = new HashSet<>();

    private static final String ID = "id";
    private static final String TYPE = "type";
    private static final String LABEL = "label";
    private static final String COMMUNITY_NAME = "community_name";
    private static final String USERNAME = "username";
    private static final String PASSWORD = "password";

    private final String deviceKeyId1 = "DeviceKeyId1";
    private final String deviceKeyId2 = "DeviceKeyId2";
    private final String deviceKeyId3 = "DeviceKeyId3";
    private final String deviceKeyId4 = "DeviceKeyId4";
    private final String deviceKeyLabel = "DeviceKeyLabel";
    private final String deviceKeyCommunityName = "DeviceKeyCommunityName";
    private final String deviceKeyUsername = "DeviceKeyUsername";
    private final String deviceKeyPassword = "DeviceKeyPassword";

    private final DeviceKey deviceKey1 = DeviceKey.createDeviceKeyUsingCommunityName(
            DeviceKeyId.deviceKeyId(deviceKeyId1), deviceKeyLabel, deviceKeyCommunityName);
    private final DeviceKey deviceKey2 = DeviceKey.createDeviceKeyUsingUsernamePassword(
            DeviceKeyId.deviceKeyId(deviceKeyId2), null, deviceKeyUsername, deviceKeyPassword);
    private final DeviceKey deviceKey3 = DeviceKey.createDeviceKeyUsingUsernamePassword(
            DeviceKeyId.deviceKeyId(deviceKeyId3), null, null, null);
    private final DeviceKey deviceKey4 = DeviceKey.createDeviceKeyUsingCommunityName(
            DeviceKeyId.deviceKeyId(deviceKeyId4), null, null);

    /**
     * Initializes test mocks and environment.
     */
    @Before
    public void setUpMocks() {
        expect(mockDeviceKeyService.getDeviceKeys()).andReturn(deviceKeySet).anyTimes();

        // Register the services needed for the test
        CodecManager codecService = new CodecManager();
        codecService.activate();
        ServiceDirectory testDirectory =
                new TestServiceDirectory()
                        .add(DeviceKeyService.class, mockDeviceKeyService)
                        .add(DeviceKeyAdminService.class, mockDeviceKeyAdminService)
                        .add(CodecService.class, codecService);

        BaseResource.setServiceDirectory(testDirectory);
    }

    /**
     * Hamcrest matcher to check that a device key representation in JSON matches
     * the actual device key.
     */
    public static class DeviceKeyJsonMatcher extends TypeSafeMatcher<JsonObject> {
        private final DeviceKey deviceKey;
        private String reason = "";

        public DeviceKeyJsonMatcher(DeviceKey deviceKeyValue) {
            deviceKey = deviceKeyValue;
        }

        @Override
        public boolean matchesSafely(JsonObject jsonHost) {
            // Check the device key id
            final String jsonId = jsonHost.get(ID).asString();
            if (!jsonId.equals(deviceKey.deviceKeyId().id().toString())) {
                reason = ID + " " + deviceKey.deviceKeyId().id().toString();
                return false;
            }

            // Check the device key label
            final String jsonLabel = (jsonHost.get(LABEL).isNull()) ? null : jsonHost.get(LABEL).asString();
            if (deviceKey.label() != null) {
                if ((jsonLabel == null) || !jsonLabel.equals(deviceKey.label())) {
                    reason = LABEL + " " + deviceKey.label();
                    return false;
                }
            }

            // Check the device key type
            final String jsonType = jsonHost.get(TYPE).asString();
            if (!jsonType.equals(deviceKey.type().toString())) {
                reason = TYPE + " " + deviceKey.type().toString();
                return false;
            }

            if (jsonType.equals(DeviceKey.Type.COMMUNITY_NAME.toString())) {
                // Check the device key community name
                final String jsonCommunityName = jsonHost.get(COMMUNITY_NAME).isNull() ?
                        null : jsonHost.get(COMMUNITY_NAME).asString();
                if (deviceKey.asCommunityName().name() != null) {
                    if (!jsonCommunityName.equals(deviceKey.asCommunityName().name().toString())) {
                        reason = COMMUNITY_NAME + " " + deviceKey.asCommunityName().name().toString();
                        return false;
                    }
                }
            } else if (jsonType.equals(DeviceKey.Type.USERNAME_PASSWORD.toString())) {
                // Check the device key username
                final String jsonUsername = jsonHost.get(USERNAME).isNull() ?
                        null : jsonHost.get(USERNAME).asString();
                if (deviceKey.asUsernamePassword().username() != null) {
                    if (!jsonUsername.equals(deviceKey.asUsernamePassword().username().toString())) {
                        reason = USERNAME + " " + deviceKey.asUsernamePassword().username().toString();
                        return false;
                    }
                }

                // Check the device key password
                final String jsonPassword = jsonHost.get(PASSWORD).isNull() ?
                        null : jsonHost.get(PASSWORD).asString();
                if (deviceKey.asUsernamePassword().password() != null) {
                    if (!jsonPassword.equals(deviceKey.asUsernamePassword().password().toString())) {
                        reason = PASSWORD + " " + deviceKey.asUsernamePassword().password().toString();
                        return false;
                    }
                }
            } else {
                reason = "Unknown " + TYPE + " " + deviceKey.type().toString();
                return false;
            }

            return true;
        }

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

    /**
     * Factory to allocate a device key array matcher.
     *
     * @param deviceKey device key object we are looking for
     * @return matcher
     */
    private static DeviceKeyJsonMatcher matchesDeviceKey(DeviceKey deviceKey) {
        return new DeviceKeyJsonMatcher(deviceKey);
    }

    /**
     * Hamcrest matcher to check that a device key is represented properly in a JSON
     * array of device keys.
     */
    public static class DeviceKeyJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
        private final DeviceKey deviceKey;
        private String reason = "";

        public DeviceKeyJsonArrayMatcher(DeviceKey deviceKeyValue) {
            deviceKey = deviceKeyValue;
        }

        @Override
        public boolean matchesSafely(JsonArray json) {
            boolean deviceKeyFound = false;
            final int expectedAttributes = 5;
            for (int jsonDeviceKeyIndex = 0; jsonDeviceKeyIndex < json.size();
                 jsonDeviceKeyIndex++) {

                final JsonObject jsonHost = json.get(jsonDeviceKeyIndex).asObject();

                // Device keys can have a variable number of attribute so we check
                // that there is a minimum number.
                if (jsonHost.names().size() < expectedAttributes) {
                    reason = "Found a device key with the wrong number of attributes";
                    return false;
                }

                final String jsonDeviceKeyId = jsonHost.get(ID).asString();
                if (jsonDeviceKeyId.equals(deviceKey.deviceKeyId().id().toString())) {
                    deviceKeyFound = true;

                    //  We found the correct device key, check the device key attribute values
                    assertThat(jsonHost, matchesDeviceKey(deviceKey));
                }
            }
            if (!deviceKeyFound) {
                reason = "Device key with id " + deviceKey.deviceKeyId().id().toString() + " was not found";
                return false;
            } else {
                return true;
            }
        }

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

    /**
     * Factory to allocate a device key array matcher.
     *
     * @param deviceKey device key object we are looking for
     * @return matcher
     */
    private static DeviceKeyJsonArrayMatcher hasDeviceKey(DeviceKey deviceKey) {
        return new DeviceKeyJsonArrayMatcher(deviceKey);
    }

    /**
     * Tests the result of the REST API GET when there are no device keys.
     */
    @Test
    public void testGetDeviceKeysEmptyArray() {
        replay(mockDeviceKeyService);

        WebTarget wt = target();
        String response = wt.path("keys").request().get(String.class);
        assertThat(response, is("{\"keys\":[]}"));

        verify(mockDeviceKeyService);
    }

    /**
     * Tests the result of the REST API GET when device keys are defined.
     */
    @Test
    public void testGetDeviceKeysArray() {
        replay(mockDeviceKeyService);
        deviceKeySet.add(deviceKey1);
        deviceKeySet.add(deviceKey2);
        deviceKeySet.add(deviceKey3);
        deviceKeySet.add(deviceKey4);

        WebTarget wt = target();
        String response = wt.path("keys").request().get(String.class);
        assertThat(response, containsString("{\"keys\":["));

        final JsonObject result = Json.parse(response).asObject();
        assertThat(result, notNullValue());

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

        final JsonArray deviceKeys = result.get("keys").asArray();
        assertThat(deviceKeys, notNullValue());
        assertEquals("Device keys array is not the correct size.", 4, deviceKeys.size());

        assertThat(deviceKeys, hasDeviceKey(deviceKey1));
        assertThat(deviceKeys, hasDeviceKey(deviceKey2));
        assertThat(deviceKeys, hasDeviceKey(deviceKey3));
        assertThat(deviceKeys, hasDeviceKey(deviceKey4));

        verify(mockDeviceKeyService);
    }

    /**
     * Tests the result of the REST API GET using a device key identifier.
     */
    @Test
    public void testGetDeviceKeyById() {
        deviceKeySet.add(deviceKey1);

        expect(mockDeviceKeyService.getDeviceKey(DeviceKeyId.deviceKeyId(deviceKeyId1)))
                .andReturn(deviceKey1)
                .anyTimes();
        replay(mockDeviceKeyService);

        WebTarget wt = target();
        String response = wt.path("keys/" + deviceKeyId1).request().get(String.class);
        final JsonObject result = Json.parse(response).asObject();
        assertThat(result, notNullValue());

        assertThat(result, matchesDeviceKey(deviceKey1));

        verify(mockDeviceKeyService);
    }

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

        expect(mockDeviceKeyService.getDeviceKey(DeviceKeyId.deviceKeyId(deviceKeyId1)))
                .andReturn(null)
                .anyTimes();
        replay(mockDeviceKeyService);

        WebTarget wt = target();
        try {
            wt.path("keys/" + deviceKeyId1).request().get(String.class);
            fail("GET of a non-existent device key did not throw an exception");
        } catch (NotFoundException ex) {
            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
        }

        verify(mockDeviceKeyService);
    }

    /**
     * Tests adding of new device key using POST via JSON stream.
     */
    @Test
    public void testPost() {

        mockDeviceKeyAdminService.addKey(anyObject());
        expectLastCall();

        replay(mockDeviceKeyAdminService);

        WebTarget wt = target();
        InputStream jsonStream = DeviceKeyWebResourceTest.class
                .getResourceAsStream("post-device-key.json");

        Response response = wt.path("keys").request(MediaType.APPLICATION_JSON_TYPE)
                .post(Entity.json(jsonStream));
        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));

        String location = response.getLocation().getPath();
        assertThat(location, Matchers.startsWith("/keys/" + deviceKeyId3));

        verify(mockDeviceKeyAdminService);
    }

    /**
     * Tests adding of a null device key using POST via JSON stream.
     */
    @Test
    public void testPostNullDeviceKey() {

        replay(mockDeviceKeyAdminService);

        WebTarget wt = target();
        try {
            wt.path("keys").request(MediaType.APPLICATION_JSON_TYPE)
                    .post(Entity.json(null), String.class);
            fail("POST of null device key did not throw an exception");
        } catch (BadRequestException ex) {
            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
        }

        verify(mockDeviceKeyAdminService);
    }

    /**
     * Tests removing a device key with DELETE request.
     */
    @Test
    public void testDelete() {
        expect(mockDeviceKeyService.getDeviceKey(DeviceKeyId.deviceKeyId(deviceKeyId2)))
                .andReturn(deviceKey2)
                .anyTimes();
        mockDeviceKeyAdminService.removeKey(anyObject());
        expectLastCall();

        replay(mockDeviceKeyService);
        replay(mockDeviceKeyAdminService);

        WebTarget wt = target();

        Response response = wt.path("keys/" + deviceKeyId2)
                .request(MediaType.APPLICATION_JSON_TYPE)
                .delete();
        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));

        verify(mockDeviceKeyService);
        verify(mockDeviceKeyAdminService);
    }

    /**
     * Tests that a DELETE of a non-existent device key throws an exception.
     */
    @Test
    public void testDeleteNonExistentDeviceKey() {
        expect(mockDeviceKeyService.getDeviceKey(anyObject()))
                .andReturn(null)
                .anyTimes();

        expectLastCall();

        replay(mockDeviceKeyService);
        replay(mockDeviceKeyAdminService);

        WebTarget wt = target();

        try {
            wt.path("keys/" + "NON_EXISTENT_DEVICE_KEY").request()
                    .delete(String.class);
            fail("Delete of a non-existent device key did not throw an exception");
        } catch (NotFoundException ex) {
            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
        }

        verify(mockDeviceKeyService);
        verify(mockDeviceKeyAdminService);
    }
}