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

        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);
    }
}