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

import static org.onosproject.net.DeviceId.deviceId;

import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import com.google.common.collect.Iterables;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.apache.karaf.shell.api.action.Option;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.TributarySlot;
import org.onosproject.net.resource.ContinuousResource;
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.Resources;
import org.onosproject.net.resource.ResourceQueryService;

import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;

/**
 * Lists registered resources.
 */
@Service
@Command(scope = "onos", name = "resources",
         description = "Lists registered resources")
public class ResourcesCommand extends AbstractShellCommand {

    @Option(name = "-a", aliases = "--available",
            description = "Output available resources only",
            required = false, multiValued = false)
    boolean availablesOnly = false;

    @Option(name = "-s", aliases = "--sort", description = "Sort output",
            required = false, multiValued = false)
    boolean sort = false;

    @Option(name = "-t", aliases = "--typeStrings", description = "List of resource types to be printed",
            required = false, multiValued = true)
    String[] typeStrings = null;

    Set<String> typesToPrint;

    @Argument(index = 0, name = "deviceIdString", description = "Device ID",
              required = false, multiValued = false)
    String deviceIdStr = null;

    @Argument(index = 1, name = "portNumberString", description = "PortNumber",
              required = false, multiValued = false)
    String portNumberStr = null;


    private ResourceQueryService resourceService;

    @Override
    protected void doExecute() {
        resourceService = get(ResourceQueryService.class);

        if (typeStrings != null) {
            typesToPrint = new HashSet<>(Arrays.asList(typeStrings));
        } else {
            typesToPrint = Collections.emptySet();
        }

        if (deviceIdStr != null && portNumberStr != null) {
            DeviceId deviceId = deviceId(deviceIdStr);
            PortNumber portNumber = PortNumber.fromString(portNumberStr);

            printResource(Resources.discrete(deviceId, portNumber).resource(), 0);
        } else if (deviceIdStr != null) {
            DeviceId deviceId = deviceId(deviceIdStr);

            printResource(Resources.discrete(deviceId).resource(), 0);
        } else {
            printResource(Resource.ROOT, 0);
        }
    }

    private void printResource(Resource resource, int level) {
        // workaround to preserve the original behavior of ResourceService#getRegisteredResources
        Set<Resource> children;
        if (resource instanceof DiscreteResource) {
            children = resourceService.getRegisteredResources(((DiscreteResource) resource).id());
        } else {
            children = Collections.emptySet();
        }

        if (resource.equals(Resource.ROOT)) {
            print("ROOT");
        } else {
            String resourceName = resource.simpleTypeName();
            if (resource instanceof ContinuousResource) {
                if (availablesOnly) {
                    // Get the total resource
                    double total = ((ContinuousResource) resource).value();
                    // Get allocated resource
                    double allocated = resourceService.getResourceAllocations(resource.id()).stream()
                            .mapToDouble(rA -> ((ContinuousResource) rA.resource()).value())
                            .sum();
                    // Difference
                    double difference = total - allocated;
                    print("%s%s: %f", Strings.repeat(" ", level),
                          resourceName, difference);
                } else {
                    print("%s%s: %f", Strings.repeat(" ", level),
                          resourceName,
                          ((ContinuousResource) resource).value());
                }
                // Continuous resource is terminal node, stop here
                return;
            } else {
                String availability = "";
                if (availablesOnly && !children.isEmpty()) {
                    // intermediate nodes cannot be omitted, print availability
                    if (resourceService.isAvailable(resource)) {
                        availability = " ✔";
                    } else {
                        availability = " ✘";
                    }
                }
                String toString = String.valueOf(resource.valueAs(Object.class).orElse(""));
                if (toString.startsWith(resourceName)) {
                    print("%s%s%s", Strings.repeat(" ", level),
                          toString, availability);
                } else {
                    print("%s%s: %s%s", Strings.repeat(" ", level),
                          resourceName,
                          toString, availability);
                }
            }
        }


        // Classify children into aggregatable terminal resources and everything else

        Set<Class<?>> aggregatableTypes = ImmutableSet.<Class<?>>builder()
                .add(VlanId.class)
                .add(MplsLabel.class)
                .build();
        // (last() resource name) -> { Resource }
        Multimap<String, Resource> aggregatables = ArrayListMultimap.create();
        List<Resource> nonAggregatable = new ArrayList<>();

        for (Resource r : children) {
            if (!isPrintTarget(r)) {
                continue;
            }

            if (r instanceof ContinuousResource) {
                // non-aggregatable terminal node
                nonAggregatable.add(r);
            } else if (Iterables.any(aggregatableTypes, r::isTypeOf)) {
                // aggregatable & terminal node
                String simpleName = r.simpleTypeName();
                aggregatables.put(simpleName, r);
            } else {
                nonAggregatable.add(r);
            }
        }

        // print aggregated (terminal)
        aggregatables.asMap().entrySet()
            .forEach(e -> {
                // for each type...
                String resourceName = e.getKey();

                RangeSet<Long> rangeSet = TreeRangeSet.create();

                // aggregate into RangeSet
                e.getValue().stream()
                    .map(res -> {
                            if (res.isTypeOf(VlanId.class)) {
                                return (long) res.valueAs(VlanId.class).get().toShort();
                            } else if (res.isTypeOf(MplsLabel.class)) {
                                return (long) res.valueAs(MplsLabel.class).get().toInt();
                            } else if (res.isTypeOf(TributarySlot.class)) {
                                return res.valueAs(TributarySlot.class).get().index();
                            }
                            // TODO support Lambda (OchSignal types)
                            return 0L;
                        })
                    .map(Range::singleton)
                    .map(range -> range.canonical(DiscreteDomain.longs()))
                    .forEach(rangeSet::add);

                print("%s%s: %s", Strings.repeat(" ", level + 1),
                      resourceName,
                      rangeSet);
            });


        // print non-aggregatables (recurse)
        if (sort) {
            nonAggregatable.stream()
                    .sorted((o1, o2) -> String.valueOf(o1.id()).compareTo(String.valueOf(o2.id())))
                    .forEach(r -> printResource(r, level + 1));
        } else {
            nonAggregatable.forEach(r -> printResource(r, level + 1));
        }
    }

    private boolean isPrintTarget(Resource resource) {
        if (typesToPrint.isEmpty()) {
            return true;
        }

        String resourceName = resource.simpleTypeName();
        if (resource instanceof DiscreteResource) {
            // TODO This distributed store access incurs overhead.
            //      This should be merged with the one in printResource()
            if (!resourceService.getRegisteredResources(((DiscreteResource) resource).id()).isEmpty()) {
                // resource which has children should be printed
                return true;
            }
            if (availablesOnly && !resourceService.isAvailable(resource)) {
                // don't print unavailable discrete resource
                return false;
            }
        } else if (!(resource instanceof ContinuousResource)) {
            log.warn("Unexpected resource class: {}", resource.getClass().getSimpleName());
            return false;
        }

        return typesToPrint.contains(resourceName);
    }
}
