/*
 * Copyright 2016 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.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.hamcrest.Matchers;
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.core.CoreService;
import org.onosproject.net.NetTestTools;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.rest.resources.CoreWebApplication;

import javax.ws.rs.core.MediaType;
import java.io.InputStream;
import java.net.HttpURLConnection;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.anyShort;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
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.APP_ID;

/**
 * Unit tests for flow objectives REST APIs.
 */
public class FlowObjectiveResourceTest extends ResourceTest {
    final FlowObjectiveService mockFlowObjectiveService = createMock(FlowObjectiveService.class);
    CoreService mockCoreService = createMock(CoreService.class);
    public static final String REST_APP_ID = "org.onosproject.rest";

    public FlowObjectiveResourceTest() {
        super(CoreWebApplication.class);
    }

    /**
     * Sets up the global values for all the tests.
     */
    @Before
    public void setUpTest() {
        // Mock Core Service
        expect(mockCoreService.getAppId(anyShort()))
                .andReturn(NetTestTools.APP_ID).anyTimes();
        expect(mockCoreService.registerApplication(REST_APP_ID))
                .andReturn(APP_ID).anyTimes();
        replay(mockCoreService);

        // Register the services needed for the test
        final CodecManager codecService = new CodecManager();
        codecService.activate();
        ServiceDirectory testDirectory =
                new TestServiceDirectory()
                        .add(FlowObjectiveService.class, mockFlowObjectiveService)
                        .add(CodecService.class, codecService)
                        .add(CoreService.class, mockCoreService);

        BaseResource.setServiceDirectory(testDirectory);
    }

    /**
     * Cleans up and verifies the mocks.
     */
    @After
    public void tearDownTest() {
        verify(mockFlowObjectiveService);
        verify(mockCoreService);
    }

    /**
     * Tests creating a filtering objective with POST.
     */
    @Test
    public void testFilteringObjectivePost() {
        mockFlowObjectiveService.filter(anyObject(), anyObject());
        prepareService();
        testObjectiveCreation("post-filter-objective.json", "of:0000000000000001", "filter");
    }

    /**
     * Tests creating a forwarding objective with POST.
     */
    @Test
    public void testForwardingObjectivePost() {
        mockFlowObjectiveService.forward(anyObject(), anyObject());
        prepareService();
        testObjectiveCreation("post-forward-objective.json", "of:0000000000000001", "forward");
    }

    /**
     * Tests creating a next objective with POST.
     */
    @Test
    public void testNextObjectivePost() {
        mockFlowObjectiveService.next(anyObject(), anyObject());
        prepareService();
        testObjectiveCreation("post-next-objective.json", "of:0000000000000001", "next");
    }

    /**
     * Tests obtaining a global unique nextId with GET.
     */
    @Test
    public void testNextId() {
        expect(mockFlowObjectiveService.allocateNextId()).andReturn(10).anyTimes();
        prepareService();

        WebResource rs = resource();
        final String response = rs.path("flowobjectives/next").get(String.class);
        final JsonObject result = Json.parse(response).asObject();
        assertThat(result, notNullValue());

        assertThat(result.names(), hasSize(1));
        assertThat(result.names().get(0), is("nextId"));
        final int jsonNextId = result.get("nextId").asInt();
        assertThat(jsonNextId, is(10));
    }

    private void prepareService() {
        expectLastCall();
        replay(mockFlowObjectiveService);
    }

    /**
     * A base class for testing various objective creation.
     *
     * @param jsonFile json file path
     * @param deviceId device id in string format
     * @param method objective method
     */
    private void testObjectiveCreation(String jsonFile, String deviceId, String method) {
        WebResource rs = resource();
        InputStream jsonStream = FlowsResourceTest.class
                .getResourceAsStream(jsonFile);

        StringBuilder sb = new StringBuilder();
        sb.append("flowobjectives");
        sb.append("/");
        sb.append(deviceId);
        sb.append("/");
        sb.append(method);

        ClientResponse response = rs.path(sb.toString())
                .type(MediaType.APPLICATION_JSON_TYPE)
                .post(ClientResponse.class, jsonStream);
        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
        String location = response.getLocation().getPath();
        assertThat(location, Matchers.startsWith("/" + sb.toString()));
    }
}
