/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.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.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);

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