/*
 * Copyright 2015-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.onosproject.cli.net;

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

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.StreamSupport;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
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.onlab.util.Bandwidth;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.OchSignal;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.IntentId;
import org.onosproject.net.resource.Resources;
import org.onosproject.net.resource.DiscreteResourceId;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceService;

/**
 * Lists allocated resources.
 */
@Command(scope = "onos", name = "allocations",
         description = "Lists allocated resources")
public class AllocationsCommand extends AbstractShellCommand {

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

    Set<String> typesToPrint;

    @Option(name = "-i", aliases = "--intentId", description = "Intent ID",
            required = false, multiValued = true)
    String[] intentStrings;

    Set<String> intentsToPrint;

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

    @Override
    protected void execute() {
        deviceService = get(DeviceService.class);
        resourceService = get(ResourceService.class);

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

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

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

            printAllocation(deviceId, portNumber, 0);
        } else if (deviceIdStr != null) {
            DeviceId deviceId = deviceId(deviceIdStr);

            printAllocation(deviceId, 0);
        } else {
            printAllocation();
        }

    }

    private void printAllocation() {
        print("ROOT");
        StreamSupport.stream(deviceService.getAvailableDevices().spliterator(), false)
            .map(Device::id)
            .forEach(did -> printAllocation(did, 1));
    }

    private void printAllocation(DeviceId did, int level) {
        print("%s%s", Strings.repeat(" ", level), did);
        StreamSupport.stream(deviceService.getPorts(did).spliterator(), false)
            .map(Port::number)
            .forEach(num -> printAllocation(did, num, level + 1));
    }

    private void printAllocation(DeviceId did, PortNumber num, int level) {
        if (level == 0) {
            // print DeviceId when Port was directly specified.
            print("%s", did);
        }
        print("%s%s", Strings.repeat(" ", level), asVerboseString(num));

        // FIXME: This workaround induces a lot of distributed store access.
        //        ResourceService should have an API to get all allocations under a parent resource.
        Set<Class<?>> subResourceTypes = ImmutableSet.<Class<?>>builder()
                .add(OchSignal.class)
                .add(VlanId.class)
                .add(MplsLabel.class)
                .add(Bandwidth.class)
                .build();

        DiscreteResourceId resourceId = Resources.discrete(did, num).id();
        for (Class<?> t : subResourceTypes) {
            resourceService.getResourceAllocations(resourceId, t).stream()
                    .filter(a -> isSubjectToPrint(a))
                    .forEach(a -> print("%s%s allocated by %s", Strings.repeat(" ", level + 1),
                            a.resource().valueAs(Object.class).orElse(""), asVerboseString(a.consumer())));

        }
    }

    private boolean isSubjectToPrint(ResourceAllocation allocation) {
        if (!intentsToPrint.isEmpty()
                && allocation.consumer() instanceof IntentId
                && !intentsToPrint.contains(allocation.consumer().toString())) {
            return false;
        }

        if (!typesToPrint.isEmpty()
                && !typesToPrint.contains(allocation.resource().simpleTypeName())) {
            return false;
        }

        return true;
    }

    /**
     * Add type name if the toString does not start with them.
     *
     * e.g., IntentId#toString result in "42"
     *       asVerboseString(id) will result in "IntentId:42"
     *
     * @param obj non-null Object to print.
     * @return verbose String representation
     */
    private static String asVerboseString(Object obj) {
        String name = obj.getClass().getSimpleName();
        String toString = String.valueOf(obj);
        if (toString.startsWith(name)) {
            return toString;
        } else {
            return String.format("%s:%s", name, toString);
        }
    }

}
