/*
 * Copyright (c) 2020, 2021, 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 8246712
 * @summary doclint incorrectly reports some HTML elements as empty
 * @modules jdk.javadoc/jdk.javadoc.internal.doclint
 * @library /tools/lib
 * @build toolbox.TestRunner toolbox.ToolBox
 * @run main EmptyHtmlTest
 */

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import com.sun.source.doctree.DocTreeVisitor;
import com.sun.source.doctree.InlineTagTree;
import jdk.javadoc.internal.doclint.DocLint;
import toolbox.TestRunner;
import toolbox.ToolBox;

public class EmptyHtmlTest extends TestRunner {

    public static void main(String... args) throws Exception {
        EmptyHtmlTest t = new EmptyHtmlTest();
        t.runTests(m -> new Object[] { Path.of(m.getName()) });
    }

    public EmptyHtmlTest() {
        super(System.err);
    }

    ToolBox tb = new ToolBox();

    /**
     * This test is intended to be future-proof, and hence detect any
     * problems in any inline tags added in the future.
     * Since there is not yet any mapping between DocTree.Kind and
     * the corresponding subtype DocTree (see javac Tree.Kind, Tree)
     * the list of all current inline tag classes is determined by
     * scanning DocTreeVisitor.
     *
     * @param base working directory for the test case
     * @throws Exception if an error occurs
     */
    @Test
    public void testInlines(Path base) throws Exception {
        Class<DocTreeVisitor> c = DocTreeVisitor.class;
        for (Method m : c.getDeclaredMethods()) {
            if (m.getName().startsWith("visit") && m.getParameterCount() == 2) {
                Class<?>[] paramTypes = m.getParameterTypes();
                Class<?> firstParamType = paramTypes[0];
                if (InlineTagTree.class.isAssignableFrom(firstParamType)) {
                    testInline(base, firstParamType);
                }
            }
        }
    }

    void testInline(Path base, Class<?> type) throws Exception {
        // the following can eventually be converted to instanceof pattern switch
        Path d = Files.createDirectories(base.resolve(type.getSimpleName()));
        switch (type.getSimpleName()) {
            case "DocRootTree" ->
                    test(d, type, "{@docRoot}");

            case "IndexTree" ->
                    test(d, type, "{@index Object}");

            case "InheritDocTree" ->
                    test(d, type, "{@inheritDoc}");

            case "LinkTree" ->
                    test(d, type, "{@link Object}");

            case "LiteralTree" ->
                    test(d, type, "{@literal abc}");

            case "ReturnTree" ->
                    test(d, type, "{@return abc}");

            case "SnippetTree" ->
                    test(d, type, """
                            {@snippet :
                                abc
                            }
                            """);

            case "SummaryTree" ->
                    test(d, type, "{@summary First sentence.}");

            case "SystemPropertyTree" ->
                    test(d, type, "{@systemProperty file.separator}");

            case "UnknownInlineTagTree" ->
                    test(d, type, "{@unknown}");

            case "ValueTree" ->
                    test(d, type, "{@value Math.PI}");

            default ->
                error("no test case provided for " + type);
        }
    }

    void test(Path base, Class<?> type, String tag) throws Exception {
        System.err.println("test " + type.getSimpleName() + " " + tag);
        Path src = base.resolve("src");
        String text = """
                /**
                 * This is a comment.
                 * <b>INSERT</b>
                 */
                 public class C {  }
                """.replace("INSERT", tag);
        tb.writeJavaFiles(src, text);

        List<String> cmdArgs = List.of(
                "-Xmsgs:html",
                "-XcustomTags:unknown",
                src.resolve("C.java").toString()
        );

        StringWriter sw = new StringWriter();
        try (PrintWriter pw = new PrintWriter(sw)) {
            new DocLint().run(pw, cmdArgs.toArray(new String[0]));
        }
        String log = sw.toString();
        if (!log.isEmpty()) {
            System.err.println("output:");
            log.lines().forEach(System.err::println);
            error("Unexpected output from doclint");
        }
    }
}
