/*
 * 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 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 com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
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.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 (jsonLink.names().size() != expectedAttributes) {
                    reason = "Found a link with the wrong number of attributes";
                    return false;
                }

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


    @Before
    public void setUp() {
        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);
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
        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);

        WebResource rs = resource();
        String response = rs.path("links").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);

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

        JsonObject result = JsonObject.readFrom(response);
        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);

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

        JsonObject result = JsonObject.readFrom(response);
        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);

        WebResource rs = resource();
        String response = rs
                .path("links")
                .queryParam("device", "src2")
                .queryParam("port", "2")
                .get(String.class);
        assertThat(response, containsString("{\"links\":["));

        JsonObject result = JsonObject.readFrom(response);
        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);

        WebResource rs = resource();
        String response = rs
                .path("links")
                .queryParam("device", "src2")
                .queryParam("port", "2")
                .queryParam("direction", "INGRESS")
                .get(String.class);
        assertThat(response, containsString("{\"links\":["));

        JsonObject result = JsonObject.readFrom(response);
        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);

        WebResource rs = resource();
        String response = rs
                .path("links")
                .queryParam("device", "src2")
                .queryParam("direction", "INGRESS")
                .get(String.class);
        assertThat(response, containsString("{\"links\":["));

        JsonObject result = JsonObject.readFrom(response);
        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));
    }
}
