/*
 * Copyright (c) 2023, 2025, 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.
 */

import java.io.Writer;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.stream.Stream;

import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;

import static org.junit.jupiter.api.Assertions.*;

/*
 * @test
 * @bug 8305457 8342936 8351435 8344706
 * @summary java.lang.IO tests
 * @library /test/lib
 * @modules jdk.internal.le
 * @run junit IO
 */
@ExtendWith(IO.TimingExtension.class)
public class IO {

    @Nested
    @EnabledOnOs({OS.LINUX, OS.MAC})
    public class OSSpecificTests {

        private static Path expect;

        @BeforeAll
        public static void prepareTTY() {
            expect = Paths.get("/usr/bin/expect"); // os-specific path
            if (!Files.exists(expect) || !Files.isExecutable(expect)) {
                Assumptions.abort("'" + expect + "' not found");
            }
            try {
                var outputAnalyzer = ProcessTools.executeProcess(
                        expect.toAbsolutePath().toString(), "-version");
                outputAnalyzer.reportDiagnosticSummary();
            } catch (Exception _) { }
        }

        /*
         * Unlike printTest, which tests a _default_ console that is normally
         * jdk.internal.org.jline.JdkConsoleProviderImpl, this test tests
         * jdk.internal.io.JdkConsoleImpl. Those console implementations operate
         * in different conditions and, thus, are tested separately.
         *
         * To test jdk.internal.io.JdkConsoleImpl one needs to ensure that both
         * conditions are met:
         *
         *   - a non-existent console provider is requested
         *   - isatty is true
         *
         * To achieve isatty, the test currently uses the EXPECT(1) Unix command,
         * which does not work for Windows. Later, a library like pty4j or JPty
         * might be used instead of EXPECT, to cover both Unix and Windows.
         */
        @ParameterizedTest
        @ValueSource(strings = {"println", "print"})
        public void outputTestInteractive(String mode) throws Exception {
            var testSrc = System.getProperty("test.src", ".");
            OutputAnalyzer output = ProcessTools.executeProcess(
                    expect.toString(),
                    Path.of(testSrc, "output.exp").toAbsolutePath().toString(),
                    System.getProperty("test.jdk") + "/bin/java",
                    "--enable-preview",
                    "-Djdk.console=gibberish",
                    Path.of(testSrc, "Output.java").toAbsolutePath().toString(),
                    mode);
            assertEquals(0, output.getExitValue());
            assertTrue(output.getStderr().isEmpty());
            output.reportDiagnosticSummary();
            String out = output.getStdout();
            // The first half of the output is produced by Console, the second
            // half is produced by IO: those halves must match.
            // Executing Console and IO in the same VM (as opposed to
            // consecutive VM runs, which are cleaner) to be able to compare string
            // representation of objects.
            assertFalse(out.isBlank());
            assertEquals(out.substring(0, out.length() / 2),
                    out.substring(out.length() / 2));
        }

        /*
         * This tests simulates terminal interaction (isatty), to check that the
         * prompt is output.
         *
         * To simulate a terminal, the test currently uses the EXPECT(1) Unix
         * command, which does not work for Windows. Later, a library like pty4j
         * or JPty might be used instead of EXPECT, to cover both Unix and Windows.
         */
        @ParameterizedTest
        @MethodSource("args")
        public void inputTestInteractive(String console, String prompt) throws Exception {
            var testSrc = System.getProperty("test.src", ".");
            var command = new ArrayList<String>();
            command.add(expect.toString());
            String expectInputName = PROMPT_NONE.equals(prompt) ? "input-no-prompt"
                                                                : "input";
            command.add(Path.of(testSrc, expectInputName + ".exp").toAbsolutePath().toString());
            command.add(System.getProperty("test.jdk") + "/bin/java");
            command.add("--enable-preview");
            if (console != null)
                command.add("-Djdk.console=" + console);
            command.add(Path.of(testSrc, "Input.java").toAbsolutePath().toString());
            command.add(prompt == null ? "0" : PROMPT_NONE.equals(prompt) ? "2" : "1");
            command.add(String.valueOf(prompt));
            OutputAnalyzer output = ProcessTools.executeProcess(command.toArray(new String[]{}));
            output.reportDiagnosticSummary();
            assertEquals(0, output.getExitValue());
        }

        private static final String PROMPT_NONE = "prompt-none";

        public static Stream<Arguments> args() {
            // cross product: consoles x prompts
            return Stream.of("jdk.internal.le", "gibberish").flatMap(console -> Stream.of(null, "?", "%s", PROMPT_NONE)
                    .map(prompt -> new String[]{console, prompt}).map(Arguments::of));
        }
    }

    @ParameterizedTest
    @ValueSource(strings = {"println", "print"})
    public void printTest(String mode) throws Exception {
        var file = Path.of(System.getProperty("test.src", "."), "Output.java")
                .toAbsolutePath().toString();
        var pb = ProcessTools.createTestJavaProcessBuilder("-Djdk.console=jdk.internal.le", "--enable-preview", file, mode);
        OutputAnalyzer output = ProcessTools.executeProcess(pb);
        assertEquals(0, output.getExitValue());
        assertTrue(output.getStderr().isEmpty());
        output.reportDiagnosticSummary();
        String out = output.getStdout();
        // The first half of the output is produced by Console, the second
        // half is produced by IO: those halves must match.
        // Executing Console and IO in the same VM (as opposed to
        // consecutive VM runs, which are cleaner) to be able to compare string
        // representation of objects.
        assertFalse(out.isBlank());
        assertEquals(out.substring(0, out.length() / 2),
                out.substring(out.length() / 2));
    }

    @Test //JDK-8342936
    public void printlnNoParamsTest() throws Exception {
        var file = Path.of("PrintlnNoParams.java");
        try (Writer w = Files.newBufferedWriter(file)) {
            w.write("""
                    import static java.lang.IO.*;
                    void main() {
                        print("1 ");
                        print("2 ");
                        print("3 ");
                        println();
                    }
                    """);
        }
        var pb = ProcessTools.createTestJavaProcessBuilder("-Djdk.console=jdk.internal.le", "--enable-preview", file.toString());
        OutputAnalyzer output = ProcessTools.executeProcess(pb);
        assertEquals(0, output.getExitValue());
        assertTrue(output.getStderr().isEmpty());
        output.reportDiagnosticSummary();
        String out = output.getStdout();
        String nl = System.getProperty("line.separator");
        assertEquals("1 2 3 " + nl, out);
    }



    // adapted from https://junit.org/junit5/docs/current/user-guide/#extensions-lifecycle-callbacks-timing-extension
    // remove after CODETOOLS-7903752 propagates to jtreg that this test is routinely run by

    public static class TimingExtension implements BeforeTestExecutionCallback,
            AfterTestExecutionCallback {

        private static final System.Logger logger = System.getLogger(
                TimingExtension.class.getName());

        private static final String START_TIME = "start time";

        @Override
        public void beforeTestExecution(ExtensionContext context) {
            getStore(context).put(START_TIME, time());
        }

        @Override
        public void afterTestExecution(ExtensionContext context) {
            Method testMethod = context.getRequiredTestMethod();
            long startTime = getStore(context).remove(START_TIME, long.class);
            long duration = time() - startTime;

            logger.log(System.Logger.Level.INFO, () ->
                    String.format("Method [%s] took %s ms.", testMethod.getName(), duration));
        }

        private ExtensionContext.Store getStore(ExtensionContext context) {
            return context.getStore(ExtensionContext.Namespace.create(getClass(),
                    context.getRequiredTestMethod()));
        }

        private long time() {
            return System.nanoTime() / 1_000_000;
        }
    }
}
