/*
 * Copyright 2016-present 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.opencord.cordvtn.cli;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.opencord.cordvtn.api.core.ServiceNetworkService;
import org.opencord.cordvtn.api.net.ServicePort;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;

/**
 * Lists VTN networks.
 */
@Command(scope = "onos", name = "cordvtn-ports",
        description = "Lists all VTN ports")
public class CordVtnPortListCommand extends AbstractShellCommand {

    private static final String FORMAT = "%-40s%-20s%-18s%-8s%s";

    @Argument(name = "networkId", description = "Network ID")
    private String networkId = null;

    @Override
    protected void execute() {
        ServiceNetworkService service = AbstractShellCommand.get(ServiceNetworkService.class);

        List<ServicePort> ports = Lists.newArrayList(service.servicePorts());
        ports.sort(Comparator.comparing(port -> port.networkId().id()));
        if (!Strings.isNullOrEmpty(networkId)) {
            ports.removeIf(port -> !port.networkId().id().equals(networkId));
        }

        if (outputJson()) {
            try {
                print("%s", mapper().writeValueAsString(json(ports)));
            } catch (JsonProcessingException e) {
                print("Failed to list networks in JSON format");
            }
        } else {
            print(FORMAT, "ID", "MAC", "IP", "VLAN", "WAN IPs");
            for (ServicePort port: ports) {
                List<String> floatingIps = port.addressPairs().stream()
                        .map(ip -> ip.ip().toString())
                        .collect(Collectors.toList());
                print(FORMAT, port.id(),
                      port.mac(),
                      port.ip(),
                      port.vlanId() != null ? port.vlanId() : "",
                      floatingIps.isEmpty() ? "" : floatingIps);
            }
        }
    }

    private JsonNode json(List<ServicePort> ports) {
        ArrayNode result = mapper().enable(INDENT_OUTPUT).createArrayNode();
        for (ServicePort port: ports) {
            ArrayNode addrPairs = mapper().createArrayNode();
            port.addressPairs().forEach(pair -> addrPairs.add(
                    mapper().createObjectNode()
                            .put("ip", pair.ip().toString())
                            .put("mac", pair.mac().toString())));

            result.add(mapper().createObjectNode()
                               .put("id", port.id().id())
                               .put("networkId", port.networkId().id())
                               .put("mac", port.mac().toString())
                               .put("ip", port.ip().toString())
                               .put("vlan", port.vlanId() != null ?
                                       port.vlanId().toString() : null)
                               .set("addressPairs", addrPairs));
        }
        return result;
    }
}
