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