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

import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
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.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.link.LinkService;

import javax.ws.rs.client.WebTarget;

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.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.NetTestTools.link;

/**
 * Unit tests for links REST APIs.
 */
public class LinksResourceTest extends ResourceTest {
    LinkService mockLinkService;

    Link link1 = link("src1", 1, "dst1", 1);
    Link link2 = link("src2", 2, "dst2", 2);
    Link link3 = link("src3", 3, "dst3", 3);

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

        public LinkJsonMatcher(Link linkValue) {
            link = linkValue;
        }

        @Override
        public boolean matchesSafely(JsonObject jsonLink) {
            JsonObject jsonSrc = jsonLink.get("src").asObject();
            String jsonSrcDevice = jsonSrc.get("device").asString();
            String jsonSrcPort = jsonSrc.get("port").asString();

            JsonObject jsonDst = jsonLink.get("dst").asObject();
            String jsonDstDevice = jsonDst.get("device").asString();
            String jsonDstPort = jsonDst.get("port").asString();

            return jsonSrcDevice.equals(link.src().deviceId().toString()) &&
                   jsonSrcPort.equals(link.src().port().toString()) &&
                   jsonDstDevice.equals(link.dst().deviceId().toString()) &&
                   jsonDstPort.equals(link.dst().port().toString());
        }

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

    /**
     * Factory to allocate an link matcher.
     *
     * @param link link object we are looking for
     * @return matcher
     */
    private static LinkJsonMatcher matchesLink(Link link) {
        return new LinkJsonMatcher(link);
    }

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

        public LinkJsonArrayMatcher(Link linkValue) {
            link = linkValue;
        }

        @Override
        public boolean matchesSafely(JsonArray json) {
            final int expectedAttributes = 2;

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

                JsonObject jsonLink = json.get(jsonLinkIndex).asObject();

                if (matchesLink(link).matchesSafely(jsonLink)) {
                    return true;
                }
            }
            return false;
        }

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

    /**
     * Factory to allocate an link array matcher.
     *
     * @param link link object we are looking for
     * @return matcher
     */
    private static LinkJsonArrayMatcher hasLink(Link link) {
        return new LinkJsonArrayMatcher(link);
    }

    /**
     * Initializes test mocks and environment.
     */
    @Before
    public void setUpTest() {
        mockLinkService = createMock(LinkService.class);

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

        BaseResource.setServiceDirectory(testDirectory);
    }

    /**
     * Tears down and verifies test mocks and environment.
     */
    @After
    public void tearDownTest() {
        verify(mockLinkService);
    }

    /**
     * Tests the result of the rest api GET when there are no links.
     */
    @Test
    public void testLinksEmptyArray() {
        expect(mockLinkService.getLinks()).andReturn(ImmutableList.of());
        replay(mockLinkService);

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

    /**
     * Tests the result of the rest api GET when there are links present.
     */
    @Test
    public void testLinks() {
        expect(mockLinkService.getLinks())
                .andReturn(ImmutableList.of(link1, link2, link3))
                .anyTimes();

        replay(mockLinkService);

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

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

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

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

        assertThat(jsonLinks, hasLink(link1));
        assertThat(jsonLinks, hasLink(link2));
        assertThat(jsonLinks, hasLink(link3));
    }

    /**
     * Tests the result of the rest api GET of links for a specific device.
     */
    @Test
    public void testLinksByDevice() {
        expect(mockLinkService.getDeviceLinks(isA(DeviceId.class)))
                .andReturn(ImmutableSet.of(link2))
                .anyTimes();

        replay(mockLinkService);

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

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

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

        JsonArray jsonLinks = result.get("links").asArray();
        assertThat(jsonLinks, notNullValue());
        assertThat(jsonLinks.size(), is(1));

        assertThat(jsonLinks, hasLink(link2));
    }

    /**
     * Tests the result of the rest api GET of links for a specific device
     * and port.
     */
    @Test
    public void testLinksByDevicePort() {

        expect(mockLinkService.getLinks(isA(ConnectPoint.class)))
                .andReturn(ImmutableSet.of(link2))
                .anyTimes();

        replay(mockLinkService);

        WebTarget wt = target();
        String response = wt
                .path("links")
                .queryParam("device", "src2")
                .queryParam("port", "2")
                .request()
                .get(String.class);
        assertThat(response, containsString("{\"links\":["));

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

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

        JsonArray jsonLinks = result.get("links").asArray();
        assertThat(jsonLinks, notNullValue());
        assertThat(jsonLinks.size(), is(1));

        assertThat(jsonLinks, hasLink(link2));
    }

    /**
     * Tests the result of the rest api GET of links for a specific
     * device, port, and direction.
     */
    @Test
    public void testLinksByDevicePortDirection() {

        expect(mockLinkService.getIngressLinks(isA(ConnectPoint.class)))
                .andReturn(ImmutableSet.of(link2))
                .anyTimes();

        replay(mockLinkService);

        WebTarget wt = target();
        String response = wt
                .path("links")
                .queryParam("device", "src2")
                .queryParam("port", "2")
                .queryParam("direction", "INGRESS")
                .request()
                .get(String.class);
        assertThat(response, containsString("{\"links\":["));

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

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

        JsonArray jsonLinks = result.get("links").asArray();
        assertThat(jsonLinks, notNullValue());
        assertThat(jsonLinks.size(), is(1));

        assertThat(jsonLinks, hasLink(link2));
    }

    /**
     * Tests the result of the rest api GET of links for a specific
     * device and direction.
     */
    @Test
    public void testLinksByDeviceDirection() {

        expect(mockLinkService.getDeviceIngressLinks(isA(DeviceId.class)))
                .andReturn(ImmutableSet.of(link2))
                .anyTimes();

        replay(mockLinkService);

        WebTarget wt = target();
        String response = wt
                .path("links")
                .queryParam("device", "src2")
                .queryParam("direction", "INGRESS")
                .request()
                .get(String.class);
        assertThat(response, containsString("{\"links\":["));

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

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

        JsonArray jsonLinks = result.get("links").asArray();
        assertThat(jsonLinks, notNullValue());
        assertThat(jsonLinks.size(), is(1));

        assertThat(jsonLinks, hasLink(link2));
    }
}
