/*
 * Copyright 2017-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.mapping.cli;

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.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.mapping.MappingEntry;
import org.onosproject.mapping.MappingKey;
import org.onosproject.mapping.MappingTreatment;
import org.onosproject.mapping.MappingValue;
import org.onosproject.mapping.MappingService;
import org.onosproject.mapping.MappingStore;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;

import java.util.List;

import static com.google.common.collect.Lists.newArrayList;

/**
 * A command for querying mapping information.
 */
@Command(scope = "onos", name = "mappings",
        description = "Lists mappings")
public class MappingsListCommand extends AbstractShellCommand {

    private static final String DB = "database";
    private static final String CACHE = "cache";

    private static final String SUMMARY_FORMAT = "deviceId=%s, mappingCount=%d";
    private static final String MAPPING_ID_FORMAT = "  id=%s";
    private static final String MAPPING_STATE_FORMAT = "  state=%s";
    private static final String MAPPING_KEY_FORMAT = "  key=%s";
    private static final String MAPPING_VALUE_FORMAT = "  value=";
    private static final String MAPPING_ACTION_FORMAT = "    action=%s";
    private static final String MAPPING_TREATMENTS_FORMAT = "    treatments=";
    private static final String MAPPING_TREATMENT_LONG_FORMAT =
            "      address=%s, instructions=%s";
    private static final String MAPPING_TREATMENT_SHORT_FORMAT = "      %s";
    private static final String JSON_FORMAT = "%s";

    private static final String TYPE_NOT_NULL = "Mapping store type should not be null";
    private static final String TYPE_ILLEGAL = "Mapping store type is not correct";

    @Argument(index = 0, name = "type",
            description = "Shows mappings with specified type",
            required = true, multiValued = false)
    private String type = null;

    @Argument(index = 1, name = "deviceId", description = "Device identity",
            required = false, multiValued = false)
    private String deviceId = null;

    @Option(name = "-s", aliases = "--short",
            description = "Print more succinct output for each mapping",
            required = false, multiValued = false)
    private boolean shortOutput = false;

    private MappingService mappingService =
            AbstractShellCommand.get(MappingService.class);
    private List<MappingEntry> mappings;

    @Override
    protected void doExecute() {

        MappingStore.Type typeEnum = getTypeEnum(type);

        DeviceService deviceService = get(DeviceService.class);
        Iterable<Device> devices = deviceService.getDevices();

        if (outputJson()) {
            print(JSON_FORMAT, json(typeEnum, devices));
        } else {
            if (deviceId != null) {
                mappings = newArrayList(mappingService.getMappingEntries(typeEnum,
                        DeviceId.deviceId(deviceId)));
                printMappings(DeviceId.deviceId(deviceId), mappings);

            } else {

                for (Device d : devices) {
                    mappings = newArrayList(mappingService.getMappingEntries(typeEnum, d.id()));
                    printMappings(d.id(), mappings);
                }
            }
        }
    }

    /**
     * Prints out mapping information.
     *
     * @param deviceId device identifier
     * @param mappings a collection of mapping
     */
    private void printMappings(DeviceId deviceId, List<MappingEntry> mappings) {

        print(SUMMARY_FORMAT, deviceId, mappings.size());

        for (MappingEntry m : mappings) {
            print(MAPPING_ID_FORMAT, Long.toHexString(m.id().value()));
            print(MAPPING_STATE_FORMAT, m.state().name());
            print(MAPPING_KEY_FORMAT, printMappingKey(m.key()));
            printMappingValue(m.value());
        }
    }

    /**
     * Prints out mapping key.
     *
     * @param key mapping key
     * @return string format of mapping key
     */
    private String printMappingKey(MappingKey key) {
        StringBuilder builder = new StringBuilder();

        if (key.address() != null) {
            builder.append(key.address().toString());
        }

        return builder.toString();
    }

    /**
     * Prints out mapping value.
     *
     * @param value mapping value
     * @return string format of mapping value
     */
    private void printMappingValue(MappingValue value) {

        print(MAPPING_VALUE_FORMAT);

        if (value.action() != null) {
            print(MAPPING_ACTION_FORMAT, value.action().toString());
        }

        if (!value.treatments().isEmpty()) {
            print(MAPPING_TREATMENTS_FORMAT);
            for (MappingTreatment treatment : value.treatments()) {
                printMappingTreatment(treatment);
            }
        }

    }

    /**
     * Prints out mapping treatment.
     *
     * @param treatment mapping treatment
     * @return string format of mapping treatment
     */
    private void printMappingTreatment(MappingTreatment treatment) {
        if (treatment != null) {
            if (shortOutput) {
                print(MAPPING_TREATMENT_SHORT_FORMAT, treatment.address());
            } else {
                print(MAPPING_TREATMENT_LONG_FORMAT, treatment.address(),
                        treatment.instructions());
            }
        }
    }

    /**
     * Returns corresponding type enumeration based on the given
     * string formatted type.
     *
     * @param type string formatted type
     * @return type enumeration
     */
    private MappingStore.Type getTypeEnum(String type) {

        if (type == null) {
            throw new IllegalArgumentException(TYPE_NOT_NULL);
        }

        switch (type) {
            case DB:
                return MappingStore.Type.MAP_DATABASE;
            case CACHE:
                return MappingStore.Type.MAP_CACHE;
            default:
                throw new IllegalArgumentException(TYPE_ILLEGAL);
        }
    }

    /**
     * Generates JSON object with the mappings of the given device.
     *
     * @param mapper   object mapper
     * @param device   device
     * @param mappings a collection of mappings
     * @return JSON object
     */
    private ObjectNode json(ObjectMapper mapper, Device device, List<MappingEntry> mappings) {
        ObjectNode result = mapper.createObjectNode();
        ArrayNode array = mapper.createArrayNode();

        mappings.forEach(mapping -> array.add(jsonForEntity(mapping, MappingEntry.class)));

        result.put("device", device.id().toString())
                .put("mappingCount", mappings.size())
                .set("mappings", array);
        return result;
    }

    /**
     * Generates JSON object with the mappings of all devices.
     *
     * @param type    mapping store type
     * @param devices a collection of devices
     * @return JSON object
     */
    private JsonNode json(MappingStore.Type type, Iterable<Device> devices) {
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode result = mapper.createArrayNode();
        for (Device device : devices) {
            result.add(json(mapper, device,
                    newArrayList(mappingService.getMappingEntries(type, device.id()))));
        }
        return result;
    }
}
