/*
 * 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.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.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.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.ResourceService;

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 available resources.
 */
@Command(scope = "onos", name = "resources",
         description = "Lists available resources")
public class ResourcesCommand extends AbstractShellCommand {

    @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 ResourceService resourceService;

    @Override
    protected void execute() {
        resourceService = get(ResourceService.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) {
        // TODO add an option to show only available resource
        // 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) {
                print("%s%s: %f", Strings.repeat(" ", level),
                                  resourceName,
                                  // Note: last() does not return, what we've registered
                                  // following does not work
                                  //((Class<?>) resource.last()).getSimpleName(),
                                  ((ContinuousResource) resource).value());
                // Continuous resource is terminal node, stop here
                return;
            } else {
                String toString = String.valueOf(resource.valueAs(Object.class).orElse(""));
                if (toString.startsWith(resourceName)) {
                    print("%s%s", Strings.repeat(" ", level),
                          toString);
                } else {
                    print("%s%s: %s", Strings.repeat(" ", level),
                          resourceName,
                          toString);
                }
            }
        }


        // 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;
            }
        } else if (!(resource instanceof ContinuousResource)) {
            log.warn("Unexpected resource class: {}", resource.getClass().getSimpleName());
            return false;
        }

        return typesToPrint.contains(resourceName);
    }
}
