/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.cli.cfg;

import java.util.Optional;
import java.util.Set;

import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Completion;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.apache.karaf.shell.api.action.Option;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.cli.AbstractShellCommand;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.cli.app.ApplicationCommandCompleter;
import org.onosproject.cli.app.ApplicationNameCompleter;

import static com.google.common.base.Strings.isNullOrEmpty;

/**
 * Manages component configuration.
 */
@Service
@Command(scope = "onos", name = "cfg",
        description = "Manages component configuration")
public class ComponentConfigCommand extends AbstractShellCommand {

    static final String GET = "get";
    static final String SET = "set";
    static final String PRESET = "preset";

    private static final String FMT = "    name=%s, type=%s, value=%s, defaultValue=%s, description=%s";
    private static final String SHORT_FMT = "    %s=%s";

    @Option(name = "-s", aliases = "--short", description = "Show short output only",
            required = false, multiValued = false)
    private boolean shortOnly = false;


    @Argument(index = 0, name = "command",
            description = "Command name (get|set|preset)",
            required = false, multiValued = false)
    @Completion(ApplicationCommandCompleter.class)
    String command = null;

    @Argument(index = 1, name = "component", description = "Component name",
            required = false, multiValued = false)
    @Completion(ApplicationNameCompleter.class)
    String component = null;

    @Argument(index = 2, name = "name", description = "Property name",
            required = false, multiValued = false)
    @Completion(ComponentPropertyNameCompleter.class)
    String name = null;

    @Argument(index = 3, name = "value", description = "Property value",
            required = false, multiValued = false)
    String value = null;

    ComponentConfigService service;

    @Override
    protected void doExecute() {
        service = get(ComponentConfigService.class);
        try {
            if (isNullOrEmpty(command)) {
                listComponents();
            } else if (command.equals(GET) && isNullOrEmpty(component)) {
                listAllComponentsProperties();
            } else if (command.equals(GET) && isNullOrEmpty(name)) {
                listComponentProperties(component);
            } else if (command.equals(GET)) {
                listComponentProperty(component, name);
            } else if (command.equals(SET) && isNullOrEmpty(value)) {
                service.unsetProperty(component, name);
            } else if (command.equals(SET)) {
                service.setProperty(component, name, value);
            } else if (command.equals(PRESET)) {
                service.preSetProperty(component, name, value);
            } else {
                error("Illegal usage");
            }
        } catch (IllegalArgumentException e) {
            error(e.getMessage());
        }
    }

    private void listAllComponentsProperties() {
        if (outputJson()) {
            print("%s", jsonComponentProperties());
        } else {
            service.getComponentNames().forEach(this::listComponentProperties);
        }
    }

    private JsonNode jsonProperty(ConfigProperty configProperty, ObjectMapper mapper) {
        return mapper.createObjectNode()
                .put("name", configProperty.name())
                .put("type", configProperty.type().toString().toLowerCase())
                .put("value", configProperty.value())
                .put("defaultValue", configProperty.defaultValue())
                .put("description", configProperty.description());
    }

    private JsonNode jsonComponent(String component, ObjectMapper mapper) {
        ObjectNode node = mapper.createObjectNode()
                .put("componentName", component);
        final ArrayNode propertiesJson = node.putArray("properties");
        Set<ConfigProperty> properties = service.getProperties(component);
        if (properties != null) {
            properties.forEach(configProperty -> propertiesJson.add(
                    jsonProperty(configProperty, mapper)));
        }
        return node;
    }

    private JsonNode jsonComponentProperties() {
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode result = mapper.createArrayNode();
        service.getComponentNames()
                .forEach(component -> result.add(jsonComponent(component, mapper)));

        return result;
    }

    private void listComponents() {
        if (outputJson()) {
            ArrayNode node = new ObjectMapper().createArrayNode();
            service.getComponentNames().forEach(node::add);
            print("%s", node);
        } else {
            service.getComponentNames().forEach(n -> print("%s", n));
        }
    }

    private void listComponentProperties(String component) {
        if (outputJson()) {
            print("%s", jsonComponent(component, new ObjectMapper()));
        } else {
            Set<ConfigProperty> props = service.getProperties(component);
            print("%s", component);
            if (props == null) {
                print("No properties for component " + component + " found");
            } else if (shortOnly) {
                props.forEach(p -> print(SHORT_FMT, p.name(), p.value()));
            } else {
                props.forEach(p -> print(FMT, p.name(), p.type().toString().toLowerCase(),
                        p.value(), p.defaultValue(), p.description()));
            }
        }
    }

    private void listComponentProperty(String component, String name) {
        Set<ConfigProperty> props = service.getProperties(component);

        if (props == null) {
            return;
        }
        Optional<ConfigProperty> property = props.stream()
                .filter(p -> p.name().equals(name)).findFirst();
        if (outputJson()) {
            print("%s", jsonProperty(property.get(), new ObjectMapper()));
        } else {
            if (!property.isPresent()) {
                print("Property " + name + " for component " + component + " not found");
                return;
            }
            ConfigProperty p = property.get();
            if (shortOnly) {
                print(SHORT_FMT, p.name(), p.value());
            } else {
                print(FMT, p.name(), p.type().toString().toLowerCase(), p.value(),
                        p.defaultValue(), p.description());
            }
        }
    }

}
