/*
 * Copyright 2016-present 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.resources;

import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
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.app.ApplicationAdminService;
import org.onosproject.app.ApplicationService;
import org.onosproject.app.ApplicationState;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.impl.ApplicationCodec;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.codec.impl.MockCodecContext;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationRole;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.Version;

import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import java.io.InputStream;
import java.net.URI;
import java.util.Optional;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

/**
 * Unit tests for applications REST APIs.
 */

public class ApplicationsResourceTest extends ResourceTest {

    private static class MockCodecContextWithAppService extends MockCodecContext {
        private ApplicationAdminService appService;

        MockCodecContextWithAppService(ApplicationAdminService appService) {
            this.appService = appService;
        }

        @Override
        @SuppressWarnings("unchecked")
        public <T> T getService(Class<T> serviceClass) {
            return (T) appService;
        }
    }

    private static class MockCodecContextWithCoreService extends MockCodecContext {
        private CoreService coreService;

        MockCodecContextWithCoreService(CoreService coreService) {
            this.coreService = coreService;
        }

        @Override
        @SuppressWarnings("unchecked")
        public <T> T getService(Class<T> serviceClass) {
            return (T) coreService;
        }
    }

    private ApplicationAdminService appService;
    private CoreService coreService;
    private ApplicationId id1 = new DefaultApplicationId(1, "app1");
    private ApplicationId id2 = new DefaultApplicationId(2, "app2");
    private ApplicationId id3 = new DefaultApplicationId(3, "app3");
    private ApplicationId id4 = new DefaultApplicationId(4, "app4");

    private static final URI FURL = URI.create("mvn:org.foo-features/1.2a/xml/features");
    private static final Version VER = Version.version(1, 2, "a", null);

    private Application app1 =
            new DefaultApplication(id1, VER, "title1",
                    "desc1", "origin1", "category1", "url1",
                    "readme1", new byte[0], ApplicationRole.ADMIN,
                    ImmutableSet.of(), Optional.of(FURL),
                    ImmutableList.of("My Feature"), ImmutableList.of());
    private Application app2 =
            new DefaultApplication(id2, VER, "title2",
                    "desc2", "origin2", "category2", "url2",
                    "readme2", new byte[0], ApplicationRole.ADMIN,
                    ImmutableSet.of(), Optional.of(FURL),
                    ImmutableList.of("My Feature"), ImmutableList.of());
    private Application app3 =
            new DefaultApplication(id3, VER, "title3",
                    "desc3", "origin3", "category3", "url3",
                    "readme3", new byte[0], ApplicationRole.ADMIN,
                    ImmutableSet.of(), Optional.of(FURL),
                    ImmutableList.of("My Feature"), ImmutableList.of());
    private Application app4 =
            new DefaultApplication(id4, VER, "title4",
                    "desc4", "origin4", "category4", "url4",
                    "readme4", new byte[0], ApplicationRole.ADMIN,
                    ImmutableSet.of(), Optional.of(FURL),
                    ImmutableList.of("My Feature"), ImmutableList.of());

    /**
     * Hamcrest matcher to check that an application representation in JSON matches
     * the actual device.
     */
    private static class AppJsonMatcher extends TypeSafeMatcher<JsonObject> {
        private final Application app;
        private String reason = "";

        public AppJsonMatcher(Application appValue) {
            app = appValue;
        }

        @Override
        public boolean matchesSafely(JsonObject jsonApp) {
            // check id
            short jsonId = (short) jsonApp.get("id").asInt();
            if (jsonId != app.id().id()) {
                reason = "id " + app.id().id();
                return false;
            }

            // check name
            String jsonName = jsonApp.get("name").asString();
            if (!jsonName.equals(app.id().name())) {
                reason = "name " + app.id().name();
                return false;
            }

            // check origin
            String jsonOrigin = jsonApp.get("origin").asString();
            if (!jsonOrigin.equals(app.origin())) {
                reason = "manufacturer " + app.origin();
                return false;
            }

            return true;
        }

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

    /**
     * Hamcrest matcher to check that an application id representation in JSON.
     */
    private static final class AppIdJsonMatcher extends TypeSafeMatcher<JsonObject> {
        private final ApplicationId appId;
        private String reason = "";

        private AppIdJsonMatcher(ApplicationId appId) {
            this.appId = appId;
        }

        @Override
        protected boolean matchesSafely(JsonObject jsonAppId) {
            // check id
            short jsonId = (short) jsonAppId.get("id").asInt();
            if (jsonId != appId.id()) {
                reason = "id " + appId.id();
                return false;
            }

            // check name
            String jsonName = jsonAppId.get("name").asString();
            if (!jsonName.equals(appId.name())) {
                reason = "name " + appId.name();
                return false;
            }

            return true;
        }

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

    /**
     * Factory to allocate an application matcher.
     *
     * @param app application object we are looking for
     * @return matcher
     */
    private static AppJsonMatcher matchesApp(Application app) {
        return new AppJsonMatcher(app);
    }

    /**
     * Factory to allocate an application Id matcher.
     *
     * @param appId application Id object we are looking for
     * @return matcher
     */
    private static AppIdJsonMatcher matchesAppId(ApplicationId appId) {
        return new AppIdJsonMatcher(appId);
    }

    /**
     * Initializes test mocks and environment.
     */
    @Before
    public void setUpMocks() {
        appService = createMock(ApplicationAdminService.class);
        coreService = createMock(CoreService.class);

        expect(appService.getId("one"))
                .andReturn(id1)
                .anyTimes();
        expect(appService.getId("two"))
                .andReturn(id2)
                .anyTimes();
        expect(appService.getId("three"))
                .andReturn(id3)
                .anyTimes();
        expect(appService.getId("four"))
                .andReturn(id4)
                .anyTimes();

        expect(appService.getApplication(id3))
                .andReturn(app3)
                .anyTimes();
        expect(appService.getState(isA(ApplicationId.class)))
                .andReturn(ApplicationState.ACTIVE)
                .anyTimes();

        // Register the services needed for the test
        CodecManager codecService = new CodecManager();
        codecService.activate();
        ServiceDirectory testDirectory =
                new TestServiceDirectory()
                        .add(ApplicationAdminService.class, appService)
                        .add(ApplicationService.class, appService)
                        .add(CoreService.class, coreService)
                        .add(CodecService.class, codecService);

        BaseResource.setServiceDirectory(testDirectory);
    }

    /**
     * Tests a GET of all applications when no applications are present.
     */
    @Test
    public void getAllApplicationsEmpty() {
        expect(appService.getApplications())
                .andReturn(ImmutableSet.of());
        replay(appService);

        WebTarget wt = target();
        String response = wt.path("applications").request().get(String.class);
        assertThat(response, is("{\"applications\":[]}"));

        verify(appService);
    }

    /**
     * Tests a GET of all applications with data.
     */
    @Test
    public void getAllApplicationsPopulated() {
        expect(appService.getApplications())
                .andReturn(ImmutableSet.of(app1, app2, app3, app4));
        replay(appService);

        WebTarget wt = target();
        String response = wt.path("applications").request().get(String.class);
        assertThat(response, containsString("{\"applications\":["));

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

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

        JsonArray jsonApps = result.get("applications").asArray();
        assertThat(jsonApps, notNullValue());
        assertThat(jsonApps.size(), is(4));

        assertThat(jsonApps.get(0).asObject(), matchesApp(app1));
        assertThat(jsonApps.get(1).asObject(), matchesApp(app2));
        assertThat(jsonApps.get(2).asObject(), matchesApp(app3));
        assertThat(jsonApps.get(3).asObject(), matchesApp(app4));

        verify(appService);
    }

    /**
     * Tests a GET of a single application.
     */
    @Test
    public void getSingleApplication() {
        replay(appService);

        WebTarget wt = target();
        String response = wt.path("applications/three").request().get(String.class);

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

        assertThat(result, matchesApp(app3));

        verify(appService);
    }

    /**
     * Tests a DELETE of a single application - this should
     * attempt to uninstall it.
     */
    @Test
    public void deleteApplication() {
        appService.uninstall(id3);
        expectLastCall();

        replay(appService);

        WebTarget wt = target();
        wt.path("applications/three").request().delete();

        verify(appService);
    }

    /**
     * Tests a DELETE of a single active application - this should
     * attempt to uninstall it.
     */
    @Test
    public void deleteActiveApplication() {
        appService.deactivate(id3);
        expectLastCall();

        replay(appService);

        WebTarget wt = target();
        wt.path("applications/three/active").request().delete();

        verify(appService);
    }

    /**
     * Tests a POST operation to the "active" URL.  This should attempt to
     * activate the application.
     */
    @Test
    public void postActiveApplication() {
        appService.activate(id3);
        expectLastCall();

        replay(appService);

        WebTarget wt = target();
        wt.path("applications/three/active").request().post(null);

        verify(appService);
    }

    /**
     * Tests a POST operation.  This should attempt to
     * install the application.
     */
    @Test
    public void postApplication() {
        expect(appService.install(isA(InputStream.class)))
                .andReturn(app4)
                .once();

        replay(appService);

        ApplicationCodec codec = new ApplicationCodec();
        String app4Json = codec.encode(app4,
                new MockCodecContextWithAppService(appService))
                .asText();

        WebTarget wt = target();
        String response = wt.path("applications").request().post(
                Entity.entity(app4Json, MediaType.APPLICATION_OCTET_STREAM), String.class);

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

        assertThat(result, matchesApp(app4));

        verify(appService);
    }

    /**
     * Tests a POST operation. This should attempt to register an on/off platform
     * application ID.
     */
    @Test
    public void postRegisterAppId() {
        expect(coreService.registerApplication("app1")).andReturn(id1).anyTimes();
        replay(coreService);

        WebTarget wt = target();
        wt.path("applications/app1/register").request().post(null);

        verify(coreService);
    }

    /**
     * Tests a GET of all application Ids when no applications are present.
     */
    @Test
    public void getAllApplicationIdsEmpty() {
        expect(coreService.getAppIds()).andReturn(ImmutableSet.of());
        replay(coreService);

        WebTarget wt = target();
        String response = wt.path("applications/ids").request().get(String.class);
        assertThat(response, is("{\"applicationIds\":[]}"));

        verify(coreService);
    }

    /**
     * Tests a GET of all application Ids.
     */
    @Test
    public void getAllApplicationIdsPopulated() {
        expect(coreService.getAppIds())
                .andReturn(ImmutableSet.of(id1, id2, id3, id4));
        replay(coreService);

        WebTarget wt = target();
        String response = wt.path("applications/ids").request().get(String.class);

        assertThat(response, containsString("{\"applicationIds\":["));

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

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

        JsonArray jsonApps = result.get("applicationIds").asArray();
        assertThat(jsonApps, notNullValue());
        assertThat(jsonApps.size(), is(4));

        assertThat(jsonApps.get(0).asObject(), matchesAppId(id1));
        assertThat(jsonApps.get(1).asObject(), matchesAppId(id2));
        assertThat(jsonApps.get(2).asObject(), matchesAppId(id3));
        assertThat(jsonApps.get(3).asObject(), matchesAppId(id4));

        verify(coreService);
    }

    /**
     * Tests a GET of an applicationId entry with the given numeric id.
     */
    @Test
    public void getAppIdByShortId() {
        expect(coreService.getAppId((short) 1)).andReturn(id1);
        replay(coreService);

        WebTarget wt = target();
        String response = wt.path("applications/ids/short")
                            .queryParam("id", 1).request().get(String.class);

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

        assertThat(result, matchesAppId(id1));

        verify(coreService);
    }

    /**
     * Tests a GET of an applicationId entry with the given application name.
     */
    @Test
    public void getAppIdByName() {
        expect(coreService.getAppId("app2")).andReturn(id2);
        replay(coreService);

        WebTarget wt = target();
        String response = wt.path("applications/ids/name")
                .queryParam("name", "app2").request().get(String.class);

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

        assertThat(result, matchesAppId(id2));

        verify(coreService);
    }
}
