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

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onosproject.app.ApplicationAdminService;
import org.onosproject.app.ApplicationService;
import org.onosproject.app.ApplicationState;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;

import java.util.Collection;

import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onosproject.app.ApplicationState.ACTIVE;

/**
 * Message handler for application view related messages.
 */
public class ApplicationViewMessageHandler extends UiMessageHandler {

    private static final String APP_DATA_REQ = "appDataRequest";
    private static final String APP_DATA_RESP = "appDataResponse";
    private static final String APPS = "apps";

    private static final String APP_MGMT_REQ = "appManagementRequest";

    private static final String APP_DETAILS_REQ = "appDetailsRequest";
    private static final String APP_DETAILS_RESP = "appDetailsResponse";
    private static final String DETAILS = "details";

    private static final String STATE = "state";
    private static final String STATE_IID = "_iconid_state";
    private static final String ID = "id";
    private static final String ICON = "icon";
    private static final String VERSION = "version";
    private static final String CATEGORY = "category";
    private static final String ORIGIN = "origin";
    private static final String TITLE = "title";
    private static final String DESC = "desc";
    private static final String URL = "url";
    private static final String README = "readme";
    private static final String ROLE = "role";
    private static final String REQUIRED_APPS = "required_apps";
    private static final String FEATURES = "features";
    private static final String PERMISSIONS = "permissions";

    private static final String ICON_ID_ACTIVE = "active";
    private static final String ICON_ID_INACTIVE = "appInactive";

    private static final String[] COL_IDS = {
            STATE, STATE_IID, ID, ICON, VERSION, CATEGORY, ORIGIN, TITLE, DESC,
            URL, README, ROLE, REQUIRED_APPS, FEATURES, PERMISSIONS
    };

    @Override
    protected Collection<RequestHandler> createRequestHandlers() {
        return ImmutableSet.of(
                new AppDataRequest(),
                new AppMgmtRequest(),
                new DetailRequestHandler()
        );
    }

    // handler for application table requests
    private final class AppDataRequest extends TableRequestHandler {
        private static final String NO_ROWS_MESSAGE = "No applications found";

        private AppDataRequest() {
            super(APP_DATA_REQ, APP_DATA_RESP, APPS);
        }

        @Override
        protected String[] getColumnIds() {
            return COL_IDS;
        }

        @Override
        protected String noRowsMessage(ObjectNode payload) {
            return NO_ROWS_MESSAGE;
        }

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            ApplicationService as = get(ApplicationService.class);
            for (Application app : as.getApplications()) {
                populateRow(tm.addRow(), app, as);
            }
        }

        private void populateRow(TableModel.Row row, Application app,
                                 ApplicationService as) {
            ApplicationId id = app.id();
            ApplicationState state = as.getState(id);
            String iconId = state == ACTIVE ? ICON_ID_ACTIVE : ICON_ID_INACTIVE;

            row.cell(STATE, state)
                    .cell(STATE_IID, iconId)
                    .cell(ID, id.name())
                    .cell(ICON, id.name())
                    .cell(VERSION, app.version())
                    .cell(CATEGORY, app.category())
                    .cell(ORIGIN, app.origin())
                    .cell(TITLE, app.title())
                    .cell(DESC, app.description())
                    .cell(URL, app.url());
        }
    }

    // handler for application management control button actions
    private final class AppMgmtRequest extends RequestHandler {
        private AppMgmtRequest() {
            super(APP_MGMT_REQ);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            String action = string(payload, "action");
            String name = string(payload, "name");
            if (action != null && name != null) {
                ApplicationAdminService service = get(ApplicationAdminService.class);
                ApplicationId appId = service.getId(name);
                if (action.equals("activate")) {
                    service.activate(appId);
                } else if (action.equals("deactivate")) {
                    service.deactivate(appId);
                } else if (action.equals("uninstall")) {
                    service.uninstall(appId);
                }
                chain(APP_DATA_REQ, sid, payload);
            }
        }
    }

    // handler for selected application detail requests
    private final class DetailRequestHandler extends RequestHandler {
        private DetailRequestHandler() {
            super(APP_DETAILS_REQ);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            String id = string(payload, ID);
            ApplicationService as = get(ApplicationService.class);

            // If the ID was not specified in the payload, use the name of the
            // most recently uploaded app.
            if (isNullOrEmpty(id)) {
                id = ApplicationResource.lastInstalledAppName;
            }

            ApplicationId appId = as.getId(id);
            ApplicationState state = as.getState(appId);
            Application app = as.getApplication(appId);
            ObjectNode data = objectNode();

            data.put(STATE, state.toString());
            data.put(ID, appId.name());
            data.put(VERSION, app.version().toString());
            data.put(ROLE, app.role().toString());
            data.put(CATEGORY, app.category());
            data.put(TITLE, app.title());
            data.put(ORIGIN, app.origin());
            data.put(README, app.readme());
            data.put(DESC, app.description());
            data.put(URL, app.url());

            // process required applications
            ArrayNode requiredApps = arrayNode();
            app.requiredApps().forEach(requiredApps::add);

            data.set(REQUIRED_APPS, requiredApps);

            // process features
            ArrayNode features = arrayNode();
            app.features().forEach(features::add);

            data.set(FEATURES, features);

            // process permissions
            ArrayNode permissions = arrayNode();
            app.permissions().forEach(p -> permissions.add(p.getName()));

            data.set(PERMISSIONS, permissions);

            ObjectNode rootNode = objectNode();
            rootNode.set(DETAILS, data);
            sendMessage(APP_DETAILS_RESP, 0, rootNode);
        }

    }
}
