/*
 * 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 com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableSet;
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 javax.ws.rs.client.WebTarget;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Set;

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;
        WebTarget wt = target();
        String response = wt.path(url).request().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"));
    }
}
