/*
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 8287121
 * @summary test ToolProvider's description API
 * @run main/othervm ToolProviderDescriptionTest
 */

import java.util.Comparator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.spi.ToolProvider;
import java.util.stream.StreamSupport;

public class ToolProviderDescriptionTest {
    public static void main(String... args) throws Exception {
        List<String> descriptions = listToolDescriptions();
        if (descriptions.isEmpty()) {
            throw new AssertionError("No tool observable?");
        }
    }

    static List<String> listToolDescriptions() {
        return StreamSupport.stream(ServiceLoader.load(ToolProvider.class).spliterator(), false)
            .sorted(Comparator.comparing(ToolProvider::name))
            .map(ToolProviderDescriptionTest::describeTool)
            .toList();
    }

    static String describeTool(ToolProvider tool) {
        String name = tool.name();
        String description = tool.description().orElse("<tool description not available>");
        return "%20s - %s".formatted(name, description);
    }
}
