/*
 * Copyright 2016 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 org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cli.Comparators;
import org.onosproject.net.region.Region;
import org.onosproject.net.region.RegionId;
import org.onosproject.net.region.RegionService;

import java.util.Collections;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;

/**
 * List Region details including membership.
 */
@Command(scope = "onos", name = "regions",
        description = "List Region details including membership")
public class RegionListCommand extends AbstractShellCommand {

    private static final String FMT = "id=%s, name=%s, type=%s";
    private static final String FMT_MASTER = "  master=%s";

    @Argument(index = 0, name = "id", description = "Region ID",
            required = false, multiValued = false)
    String id = null;

    @Override
    protected void execute() {
        RegionService regionService = get(RegionService.class);

        if (id == null) {
            for (Region region : getSortedRegions(regionService)) {
                printRegion(region);
            }
        } else {
            Region region = regionService.getRegion(RegionId.regionId(id));

            if (region == null) {
                error("No such region %s", id);
            } else {
                printRegion(region);
            }
        }
    }

    /**
     * Returns the list of regions sorted using the region identifier.
     *
     * @param service region service
     * @return sorted region list
     */
    protected List<Region> getSortedRegions(RegionService service) {
        List<Region> regions = newArrayList(service.getRegions());
        Collections.sort(regions, Comparators.REGION_COMPARATOR);
        return regions;
    }

    private void printRegion(Region region) {
        print(FMT, region.id(), region.name(), region.type());
        region.masters().forEach(m -> print(FMT_MASTER, m));
    }
}
