/*
 * 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.TributarySlot;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.IntentId;
import org.onosproject.net.resource.ResourceConsumerId;
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)
                .add(TributarySlot.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.consumerId())));

        }
    }

    private boolean isSubjectToPrint(ResourceAllocation allocation) {
        if (!intentsToPrint.isEmpty()
                && allocation.consumerId().isClassOf(IntentId.class)
                && !intentsToPrint.contains(allocation.consumerId().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);
        }
    }

    private static String asVerboseString(ResourceConsumerId consumerId) {
        return String.format("%s:%s", consumerId.consumerClass(), consumerId.value());
    }

}
