/*
 * Copyright (c) 2024, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package java.lang;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOError;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * A collection of static methods that provide convenient access to {@link System#in}
 * and {@link System#out} for line-oriented input and output.
 * <p>
 * The {@link #readln()} and {@link #readln(String)} methods decode bytes read from
 * {@code System.in} into characters. The charset used for decoding is specified by the
 * {@link System##stdin.encoding stdin.encoding} property. If this property is not present,
 * or if the charset it names cannot be loaded, then UTF-8 is used instead. Decoding
 * always replaces malformed and unmappable byte sequences with the charset's default
 * replacement string.
 * <p>
 * Charset decoding is set up upon the first call to one of the {@code readln} methods.
 * Decoding may buffer additional bytes beyond those that have been decoded to characters
 * returned to the application. After the first call to one of the {@code readln} methods,
 * any subsequent use of {@code System.in} results in unspecified behavior.
 *
 * @apiNote
 * The expected use case is that certain applications will use only the {@code readln}
 * methods to read from the standard input, and they will not mix these calls with
 * other techniques for reading from {@code System.in}.
 *
 * @since 25
 */
public final class IO {

    /*
     * We are deliberately not including printf, at least not initially, for
     * the following reasons. First, it introduces a rather cryptic and arcane
     * formatting language that isn't really suited to beginners. Second, it
     * is inherently localizable, which drags in a whole bunch of issues about
     * what locale should be used for formatting, the possible inclusion of
     * an overload with an explicit Locale parameter, and so forth. These issues
     * are best avoided for the time being. Third, when string templates come
     * along, they might offer a better alternative to printf-style formatting,
     * so it's best not be saddled with this unnecessarily.
     */

    /*
     * Notes on flushing. We want flushing to occur after every call to println
     * and print, so that the user can see output immediately. This could be
     * important if the user calls print() to issue a prompt before calling
     * readln() instead of the readln(prompt) overload. It's also important to
     * flush after print() in case the user is relying on print() to emit output
     * as sort of a progress indicator.
     *
     * We rely on System.out to have autoflush enabled, which flushes after every
     * println() call, so we needn't flush again. We flush unconditionally after
     * calls to print(). Since System.out is doing a lot of flushing anyway, there
     * isn't much point trying to make this conditional, for example, only if
     * stdout is connected to a terminal.
     */

    private IO() {
        throw new Error("no instances");
    }

    /**
     * Writes a string representation of the specified object and then writes
     * a line separator to the standard output.
     *
     * <p> The effect is as if {@link java.io.PrintStream#println(Object) println(obj)}
     * had been called on {@code System.out}.
     *
     * @param obj the object to print, may be {@code null}
     */
    public static void println(Object obj) {
        System.out.println(obj);
    }

    /**
     * Writes a line separator to the standard output.
     *
     * <p> The effect is as if {@link java.io.PrintStream#println() println()}
     * had been called on {@code System.out}.
     */
    public static void println() {
        System.out.println();
    }

    /**
     * Writes a string representation of the specified object to the
     * standard output.
     *
     * <p> The effect is as if {@link java.io.PrintStream#print(Object) print(obj)}
     * had been called on {@code System.out}.
     *
     * @param obj the object to print, may be {@code null}
     */
    public static void print(Object obj) {
        var out = System.out;
        out.print(obj);
        out.flush();
    }

    /**
     * Reads a single line of text from the standard input.
     * <p>
     * One line is read from the decoded input as if by
     * {@link java.io.BufferedReader#readLine() BufferedReader.readLine()}
     * and then the result is returned.
     * <p>
     * If necessary, this method first sets up charset decoding, as described in
     * above in the class specification.
     *
     * @return a string containing the line read from the standard input, not
     * including any line separator characters. Returns {@code null} if an
     * end of stream has been reached without having read any characters.
     *
     * @throws IOError if an I/O error occurs
     */
    public static String readln() {
        try {
            return reader().readLine();
        } catch (IOException ioe) {
            throw new IOError(ioe);
        }
    }

    /**
     * Writes a prompt and then reads a line of input.
     * <p>
     * Writes a prompt as if by calling {@link #print print}, and then reads a single
     * line of text as if by calling {@link #readln() readln}.
     * <p>
     * If necessary, this method first sets up charset decoding, as described in
     * above in the class specification.
     *
     * @param prompt the prompt string, may be {@code null}
     *
     * @return a string containing the line read from the standard input, not
     * including any line separator characters. Returns {@code null} if an
     * end of stream has been reached without having read any characters.
     *
     * @throws IOError if an I/O error occurs
     */
    public static String readln(String prompt) {
        print(prompt);
        return readln();
    }

    /**
     * The BufferedReader used by readln(). Initialized under a class lock by
     * the reader() method. All access should be through the reader() method.
     */
    private static BufferedReader br;

    /**
     * On the first call, creates an InputStreamReader to decode characters from
     * System.in, wraps it in a BufferedReader, and returns the BufferedReader.
     * These objects are cached and returned by subsequent calls.
     *
     * @return the internal BufferedReader instance
     */
    static synchronized BufferedReader reader() {
        if (br == null) {
            String enc = System.getProperty("stdin.encoding", "");
            Charset cs = Charset.forName(enc, StandardCharsets.UTF_8);
            br = new BufferedReader(new InputStreamReader(System.in, cs));
        }
        return br;
    }
}
