/*
 * 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.app.impl;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationListener;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStoreAdapter;
import org.onosproject.common.app.ApplicationArchive;
import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.DefaultApplicationId;

import java.io.InputStream;
import java.net.URI;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import static org.junit.Assert.*;
import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.onosproject.app.ApplicationState.ACTIVE;
import static org.onosproject.app.ApplicationState.INSTALLED;
import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
import static org.onosproject.net.NetTestTools.injectEventDispatcher;

/**
 * Test of the application manager implementation.
 */
public class ApplicationManagerTest {

    public static final DefaultApplicationId APP_ID = new DefaultApplicationId(1, APP_NAME);

    private ApplicationManager mgr = new ApplicationManager();
    private ApplicationListener listener = new TestListener();

    private boolean deactivated = false;

    @Before
    public void setUp() {
        injectEventDispatcher(mgr, new TestEventDispatcher());
        mgr.featuresService = new TestFeaturesService();
        mgr.store = new TestStore();
        mgr.activate();
        mgr.addListener(listener);
    }

    @After
    public void tearDown() {
        mgr.removeListener(listener);
        mgr.deactivate();
    }

    private void validate(Application app) {
        assertEquals("incorrect name", APP_NAME, app.id().name());
        assertEquals("incorrect version", VER, app.version());
        assertEquals("incorrect origin", ORIGIN, app.origin());

        assertEquals("incorrect description", DESC, app.description());
        assertEquals("incorrect features URI", FURL, app.featuresRepo().get());
        assertEquals("incorrect features", FEATURES, app.features());
    }

    @Test
    public void install() {
        InputStream stream = ApplicationArchive.class.getResourceAsStream("app.zip");
        Application app = mgr.install(stream);
        validate(app);
        assertEquals("incorrect features URI used", app.featuresRepo().get(),
                     ((TestFeaturesService) mgr.featuresService).uri);
        assertEquals("incorrect app count", 1, mgr.getApplications().size());
        assertEquals("incorrect app", app, mgr.getApplication(APP_ID));
        assertEquals("incorrect app state", INSTALLED, mgr.getState(APP_ID));
        mgr.registerDeactivateHook(app.id(), this::deactivateHook);
    }

    private void deactivateHook() {
        deactivated = true;
    }

    @Test
    public void uninstall() {
        install();
        mgr.uninstall(APP_ID);
        assertEquals("incorrect app count", 0, mgr.getApplications().size());
    }

    @Test
    public void activate() {
        install();
        mgr.activate(APP_ID);
        assertEquals("incorrect app state", ACTIVE, mgr.getState(APP_ID));
        assertFalse("preDeactivate hook wrongly called", deactivated);
    }

    @Test
    public void deactivate() {
        activate();
        mgr.deactivate(APP_ID);
        assertEquals("incorrect app state", INSTALLED, mgr.getState(APP_ID));
        assertTrue("preDeactivate hook not called", deactivated);
    }


    private class TestListener implements ApplicationListener {
        private ApplicationEvent event;

        @Override
        public void event(ApplicationEvent event) {
            this.event = event;
        }
    }

    private class TestStore extends ApplicationStoreAdapter {

        private Application app;
        private ApplicationState state;

        @Override
        public Application create(InputStream appDescStream) {
            app = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, CATEGORY,
                                         URL, README, ICON, ROLE, PERMS,
                                         Optional.of(FURL), FEATURES, ImmutableList.of());
            state = INSTALLED;
            delegate.notify(new ApplicationEvent(APP_INSTALLED, app));
            return app;
        }

        @Override
        public Set<Application> getApplications() {
            return app != null ? ImmutableSet.of(app) : ImmutableSet.of();
        }

        @Override
        public Application getApplication(ApplicationId appId) {
            return app;
        }

        @Override
        public void remove(ApplicationId appId) {
            delegate.notify(new ApplicationEvent(APP_UNINSTALLED, app));
            app = null;
            state = null;
        }

        @Override
        public ApplicationState getState(ApplicationId appId) {
            return state;
        }

        @Override
        public void activate(ApplicationId appId) {
            state = ApplicationState.ACTIVE;
            delegate.notify(new ApplicationEvent(APP_ACTIVATED, app));
        }

        @Override
        public void deactivate(ApplicationId appId) {
            state = INSTALLED;
            delegate.notify(new ApplicationEvent(APP_DEACTIVATED, app));
        }

        @Override
        public ApplicationId getId(String name) {
            return new DefaultApplicationId(0, name);
        }
    }

    private class TestFeaturesService extends FeaturesServiceAdapter {
        private URI uri;
        private Set<String> features = new HashSet<>();

        @Override
        public void addRepository(URI uri) throws Exception {
            this.uri = uri;
        }

        @Override
        public void removeRepository(URI uri) throws Exception {
            this.uri = null;
        }

        @Override
        public void installFeature(String name) throws Exception {
            features.add(name);
        }

        @Override
        public void uninstallFeature(String name) throws Exception {
            features.remove(name);
        }
    }

}