/*
 * 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.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Set;

import com.eclipsesource.json.Json;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
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.ElementId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.topology.PathService;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
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.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.createPath;
import static org.onosproject.net.NetTestTools.did;
import static org.onosproject.net.NetTestTools.hid;

/**
 * Unit tests for paths REST APIs.
 */
public class PathsResourceTest extends ResourceTest {
    Path path1 = createPath("dev1", "dev2");
    Path path2 = createPath("dev2", "dev3");
    Set<Path> paths = ImmutableSet.of(path1, path2);

    final PathService mockPathService = createMock(PathService.class);

    /**
     * Hamcrest matcher for a path and its JSON representation.
     */
    private final class PathJsonMatcher extends TypeSafeDiagnosingMatcher<JsonObject> {

        private final Path path;

        /**
         * Creates the matcher.
         *
         * @param pathValue the path object to match
         */
        private PathJsonMatcher(Path pathValue) {
            path = pathValue;
        }

        @Override
        public boolean matchesSafely(JsonObject pathJson, Description description) {

            double jsonCost = pathJson.get("cost").asDouble();
            if (jsonCost != path.cost()) {
                description.appendText("src device was " + jsonCost);
                return false;
            }

            JsonArray jsonLinks = pathJson.get("links").asArray();
            assertThat(jsonLinks.size(), is(path.links().size()));

            for (int linkIndex = 0; linkIndex < jsonLinks.size(); linkIndex++) {
                Link link = path.links().get(linkIndex);
                JsonObject jsonLink = jsonLinks.get(0).asObject();

                JsonObject jsonLinkSrc = jsonLink.get("src").asObject();
                String srcDevice = jsonLinkSrc.get("device").asString();
                if (!srcDevice.equals(link.src().deviceId().toString())) {
                    description.appendText("src device was " + jsonLinkSrc);
                    return false;
                }

                JsonObject jsonLinkDst = jsonLink.get("dst").asObject();
                String dstDevice = jsonLinkDst.get("device").asString();
                if (!dstDevice.equals(link.dst().deviceId().toString())) {
                    description.appendText("dst device was " + jsonLinkDst);
                    return false;
                }
            }

            return true;
        }

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

    /**
     * Factory to allocate an connect point matcher.
     *
     * @param path path object we are looking for
     * @return matcher
     */
    private PathJsonMatcher matchesPath(Path path) {
        return new PathJsonMatcher(path);
    }

    /**
     * Initializes test mocks and environment.
     */
    @Before
    public void setUpTest() {

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

        BaseResource.setServiceDirectory(testDirectory);
    }

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

    /**
     * Tests a REST path GET for the given endpoints.
     *
     * @param srcElement source element of the path
     * @param dstElement destination element of the path
     *
     * @throws UnsupportedEncodingException
     */
    private void runTest(ElementId srcElement, ElementId dstElement)
                 throws UnsupportedEncodingException {
        expect(mockPathService.getPaths(srcElement, dstElement))
                .andReturn(paths)
                .once();
        replay(mockPathService);

        String srcId = URLEncoder.encode(srcElement.toString(),
                                         StandardCharsets.UTF_8.name());
        String dstId = URLEncoder.encode(dstElement.toString(),
                                         StandardCharsets.UTF_8.name());

        String url = "paths/" + srcId + "/" + dstId;
        WebResource rs = resource();
        String response = rs.path(url).get(String.class);
        assertThat(response, containsString("{\"paths\":["));

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

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

        JsonArray jsonPaths = result.get("paths").asArray();
        assertThat(jsonPaths, notNullValue());
        assertThat(jsonPaths.size(), is(2));

        JsonObject path1Json = jsonPaths.get(0).asObject();
        assertThat(path1Json, matchesPath(path1));

        JsonObject path2Json = jsonPaths.get(1).asObject();
        assertThat(path2Json, matchesPath(path2));
    }

    /**
     * Tests a path between two hosts.
     *
     * @throws UnsupportedEncodingException if UTF-8 not found
     */
    @Test
    public void hostToHost() throws UnsupportedEncodingException {
        runTest(hid("01:23:45:67:89:AB/2"), hid("AB:89:67:45:23:01/4"));
    }

    /**
     * Tests a path with a host as the source and a switch as the destination.
     *
     * @throws UnsupportedEncodingException if UTF-8 not found
     */
    @Test
    public void hostToDevice() throws UnsupportedEncodingException {
        runTest(hid("01:23:45:67:89:AB/2"), did("switch1"));
    }

    /**
     * Tests a path with a switch as the source and a host as the destination.
     *
     * @throws UnsupportedEncodingException if UTF-8 not found
     */
    @Test
    public void deviceToHost() throws UnsupportedEncodingException {
        runTest(did("switch1"), hid("01:23:45:67:89:AB/2"));
    }

    /**
     * Tests a path between two switches.
     *
     * @throws UnsupportedEncodingException if UTF-8 not found
     */
    @Test
    public void deviceToDevice() throws UnsupportedEncodingException {
        runTest(did("switch1"), did("switch2"));
    }
}
