/*
 * 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, 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);
        }
    }

}