/*
 * 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.store.trivial;

import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.app.ApplicationDescription;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStore;
import org.onosproject.common.app.ApplicationArchive;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.Permission;
import org.slf4j.Logger;

import java.io.InputStream;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.onosproject.app.ApplicationState.ACTIVE;
import static org.onosproject.app.ApplicationState.INSTALLED;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Manages inventory of network control applications.
 */
@Component(immediate = true)
@Service
public class SimpleApplicationStore extends ApplicationArchive implements ApplicationStore {

    private final Logger log = getLogger(getClass());

    // App inventory & states
    private final ConcurrentMap<ApplicationId, DefaultApplication> apps = new ConcurrentHashMap<>();
    private final ConcurrentMap<ApplicationId, ApplicationState> states = new ConcurrentHashMap<>();
    private final ConcurrentMap<ApplicationId, Set<Permission>> permissions = new ConcurrentHashMap<>();

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ApplicationIdStore idStore;

    @Activate
    public void activate() {
        loadFromDisk();
        log.info("Started");
    }

    private void loadFromDisk() {
        for (String name : getApplicationNames()) {
            ApplicationId appId = idStore.registerApplication(name);
            ApplicationDescription appDesc = getApplicationDescription(name);
            DefaultApplication app =
                    new DefaultApplication(appId, appDesc.version(),
                                           appDesc.description(), appDesc.origin(),
                                           appDesc.role(), appDesc.permissions(),
                                           appDesc.featuresRepo(), appDesc.features());
            apps.put(appId, app);
            states.put(appId, isActive(name) ? INSTALLED : ACTIVE);
            // load app permissions
        }
    }

    @Deactivate
    public void deactivate() {
        apps.clear();
        states.clear();
        permissions.clear();
        log.info("Stopped");
    }

    @Override
    public Set<Application> getApplications() {
        return ImmutableSet.copyOf(apps.values());
    }

    @Override
    public ApplicationId getId(String name) {
        return idStore.getAppId(name);
    }

    @Override
    public Application getApplication(ApplicationId appId) {
        return apps.get(appId);
    }

    @Override
    public ApplicationState getState(ApplicationId appId) {
        return states.get(appId);
    }

    @Override
    public Application create(InputStream appDescStream) {
        ApplicationDescription appDesc = saveApplication(appDescStream);
        ApplicationId appId = idStore.registerApplication(appDesc.name());
        DefaultApplication app =
                new DefaultApplication(appId, appDesc.version(), appDesc.description(),
                                       appDesc.origin(), appDesc.role(), appDesc.permissions(),
                                       appDesc.featuresRepo(), appDesc.features());
        apps.put(appId, app);
        states.put(appId, INSTALLED);
        delegate.notify(new ApplicationEvent(APP_INSTALLED, app));
        return app;
    }

    @Override
    public void remove(ApplicationId appId) {
        Application app = apps.remove(appId);
        if (app != null) {
            states.remove(appId);
            delegate.notify(new ApplicationEvent(APP_UNINSTALLED, app));
            purgeApplication(app.id().name());
        }
    }

    @Override
    public void activate(ApplicationId appId) {
        Application app = apps.get(appId);
        if (app != null) {
            setActive(appId.name());
            states.put(appId, ACTIVE);
            delegate.notify(new ApplicationEvent(APP_ACTIVATED, app));
        }
    }

    @Override
    public void deactivate(ApplicationId appId) {
        Application app = apps.get(appId);
        if (app != null) {
            clearActive(appId.name());
            states.put(appId, INSTALLED);
            delegate.notify(new ApplicationEvent(APP_DEACTIVATED, app));
        }
    }

    @Override
    public Set<Permission> getPermissions(ApplicationId appId) {
        return permissions.get(appId);
    }

    @Override
    public void setPermissions(ApplicationId appId, Set<Permission> permissions) {
        Application app = getApplication(appId);
        if (app != null) {
            this.permissions.put(appId, permissions);
            delegate.notify(new ApplicationEvent(APP_PERMISSIONS_CHANGED, app));
        }
    }
}
