/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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 java.io;

import java.security.AccessController;
import java.util.Formatter;
import java.util.IllegalFormatException;
import java.util.Locale;

import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;

/**
 * Wraps either an existing {@link OutputStream} or an existing {@link Writer}
 * and provides convenience methods for printing common data types in a human
 * readable format. No {@code IOException} is thrown by this class. Instead,
 * callers should use {@link #checkError()} to see if a problem has occurred in
 * this writer.
 */
public class PrintWriter extends Writer {
    /**
     * The writer to print data to.
     */
    protected Writer out;

    /**
     * Indicates whether this PrintWriter is in an error state.
     */
    private boolean ioError;

    /**
     * Indicates whether or not this PrintWriter should flush its contents after
     * printing a new line.
     */
    private boolean autoflush;

    private final String lineSeparator = AccessController
            .doPrivileged(new PriviAction<String>("line.separator")); //$NON-NLS-1$

    /**
     * Constructs a new {@code PrintWriter} with {@code out} as its target
     * stream. By default, the new print writer does not automatically flush its
     * contents to the target stream when a newline is encountered.
     * 
     * @param out
     *            the target output stream.
     * @throws NullPointerException
     *             if {@code out} is {@code null}.
     */
    public PrintWriter(OutputStream out) {
        this(new OutputStreamWriter(out), false);
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code out} as its target
     * stream. The parameter {@code autoflush} determines if the print writer
     * automatically flushes its contents to the target stream when a newline is
     * encountered.
     * 
     * @param out
     *            the target output stream.
     * @param autoflush
     *            indicates whether contents are flushed upon encountering a
     *            newline sequence.
     * @throws NullPointerException
     *             if {@code out} is {@code null}.
     */
    public PrintWriter(OutputStream out, boolean autoflush) {
        this(new OutputStreamWriter(out), autoflush);
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code wr} as its target
     * writer. By default, the new print writer does not automatically flush its
     * contents to the target writer when a newline is encountered.
     * 
     * @param wr
     *            the target writer.
     * @throws NullPointerException
     *             if {@code wr} is {@code null}.
     */
    public PrintWriter(Writer wr) {
        this(wr, false);
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code out} as its target
     * writer. The parameter {@code autoflush} determines if the print writer
     * automatically flushes its contents to the target writer when a newline is
     * encountered.
     * 
     * @param wr
     *            the target writer.
     * @param autoflush
     *            indicates whether to flush contents upon encountering a
     *            newline sequence.
     * @throws NullPointerException
     *             if {@code out} is {@code null}.
     */
    public PrintWriter(Writer wr, boolean autoflush) {
        super(wr);
        this.autoflush = autoflush;
        out = wr;
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code file} as its target. The
     * virtual machine's default character set is used for character encoding.
     * The print writer does not automatically flush its contents to the target
     * file when a newline is encountered. The output to the file is buffered.
     * 
     * @param file
     *            the target file. If the file already exists, its contents are
     *            removed, otherwise a new file is created.
     * @throws FileNotFoundException
     *             if an error occurs while opening or creating the target file.
     * @throws SecurityException
     *             if a security manager exists and it denies writing to the
     *             target file.
     */
    public PrintWriter(File file) throws FileNotFoundException {
        this(new OutputStreamWriter(new BufferedOutputStream(
                new FileOutputStream(file))), false);
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code file} as its target. The
     * character set named {@code csn} is used for character encoding.
     * The print writer does not automatically flush its contents to the target
     * file when a newline is encountered. The output to the file is buffered.
     * 
     * @param file
     *            the target file. If the file already exists, its contents are
     *            removed, otherwise a new file is created.
     * @param csn
     *            the name of the character set used for character encoding.
     * @throws FileNotFoundException
     *             if an error occurs while opening or creating the target file.
     * @throws NullPointerException
     *             if {@code csn} is {@code null}.
     * @throws SecurityException
     *             if a security manager exists and it denies writing to the
     *             target file.
     * @throws UnsupportedEncodingException
     *             if the encoding specified by {@code csn} is not supported.
     */
    public PrintWriter(File file, String csn) throws FileNotFoundException,
            UnsupportedEncodingException {
        this(new OutputStreamWriter(new BufferedOutputStream(
                new FileOutputStream(file)), csn), false);
    }

    /**
     * Constructs a new {@code PrintWriter} with the file identified by {@code
     * fileName} as its target. The virtual machine's default character set is
     * used for character encoding. The print writer does not automatically
     * flush its contents to the target file when a newline is encountered. The
     * output to the file is buffered.
     * 
     * @param fileName
     *            the target file's name. If the file already exists, its
     *            contents are removed, otherwise a new file is created.
     * @throws FileNotFoundException
     *             if an error occurs while opening or creating the target file.
     * @throws SecurityException
     *             if a security manager exists and it denies writing to the
     *             target file.
     */
    public PrintWriter(String fileName) throws FileNotFoundException {
        this(new OutputStreamWriter(new BufferedOutputStream(
                new FileOutputStream(fileName))), false);
    }

     /**
     * Constructs a new {@code PrintWriter} with the file identified by {@code
     * fileName} as its target. The character set named {@code csn} is used for
     * character encoding. The print writer does not automatically flush its
     * contents to the target file when a newline is encountered. The output to
     * the file is buffered.
     * 
     * @param fileName
     *            the target file's name. If the file already exists, its
     *            contents are removed, otherwise a new file is created.
     * @param csn
     *            the name of the character set used for character encoding.
     * @throws FileNotFoundException
     *             if an error occurs while opening or creating the target file.
     * @throws NullPointerException
     *             if {@code csn} is {@code null}.
     * @throws SecurityException
     *             if a security manager exists and it denies writing to the
     *             target file.
     * @throws UnsupportedEncodingException
     *             if the encoding specified by {@code csn} is not supported.
     */
    public PrintWriter(String fileName, String csn)
            throws FileNotFoundException, UnsupportedEncodingException {
        this(new OutputStreamWriter(new BufferedOutputStream(
                new FileOutputStream(fileName)), csn), false);
    }

    /**
     * Flushes this writer and returns the value of the error flag.
     * 
     * @return {@code true} if either an {@code IOException} has been thrown
     *         previously or if {@code setError()} has been called;
     *         {@code false} otherwise.
     * @see #setError()
     */
    public boolean checkError() {
        Writer delegate = out;
        if (delegate == null) {
            return ioError;
        }

        flush();
        return ioError || delegate.checkError();
    }

    /**
     * Closes this print writer. Flushes this writer and then closes the target.
     * If an I/O error occurs, this writer's error flag is set to {@code true}.
     */
    @Override
    public void close() {
        synchronized (lock) {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    setError();
                }
                out = null;
            }
        }
    }

    /**
     * Ensures that all pending data is sent out to the target. It also
     * flushes the target. If an I/O error occurs, this writer's error
     * state is set to {@code true}.
     */
    @Override
    public void flush() {
        synchronized (lock) {
            if (out != null) {
                try {
                    out.flush();
                } catch (IOException e) {
                    setError();
                }
            } else {
                setError();
            }
        }
    }

    /**
     * Writes a string formatted by an intermediate {@code Formatter} to the
     * target using the specified format string and arguments. For the locale,
     * the default value of the current virtual machine instance is used. If
     * automatic flushing is enabled then the buffer is flushed as well.
     * 
     * @param format
     *            the format string used for {@link java.util.Formatter#format}.
     * @param args
     *            the list of arguments passed to the formatter. If there are
     *            more arguments than required by the {@code format} string,
     *            then the additional arguments are ignored.
     * @return this writer.
     * @throws IllegalFormatException
     *             if the format string is illegal or incompatible with the
     *             arguments, if there are not enough arguments or if any other
     *             error regarding the format string or arguments is detected.
     * @throws NullPointerException
     *             if {@code format} is {@code null}.
     */
    public PrintWriter format(String format, Object... args) {
        return format(Locale.getDefault(), format, args);
    }

    /**
     * Writes a string formatted by an intermediate {@code Formatter} to the
     * target using the specified locale, format string and arguments. If
     * automatic flushing is enabled then this writer is flushed.
     * 
     * @param l
     *            the locale used in the method. No localization will be applied
     *            if {@code l} is {@code null}.
     * @param format
     *            the format string used for {@link java.util.Formatter#format}.
     * @param args
     *            the list of arguments passed to the formatter. If there are
     *            more arguments than required by the {@code format} string,
     *            then the additional arguments are ignored.
     * @return this writer.
     * @throws IllegalFormatException
     *             if the format string is illegal or incompatible with the
     *             arguments, if there are not enough arguments or if any other
     *             error regarding the format string or arguments is detected.
     * @throws NullPointerException
     *             if {@code format} is {@code null}.
     */
    public PrintWriter format(Locale l, String format, Object... args) {
        if (format == null) {
            throw new NullPointerException(Msg.getString("K0351")); //$NON-NLS-1$
        }
        new Formatter(this, l).format(format, args);
        if (autoflush) {
            flush();
        }
        return this;
    }

    /**
     * Prints a formatted string. The behavior of this method is the same as
     * this writer's {@code #format(String, Object...)} method. For the locale,
     * the default value of the current virtual machine instance is used.
     * 
     * @param format
     *            the format string used for {@link java.util.Formatter#format}.
     * @param args
     *            the list of arguments passed to the formatter. If there are
     *            more arguments than required by the {@code format} string,
     *            then the additional arguments are ignored.
     * @return this writer.
     * @throws IllegalFormatException
     *             if the format string is illegal or incompatible with the
     *             arguments, if there are not enough arguments or if any other
     *             error regarding the format string or arguments is detected.
     * @throws NullPointerException
     *             if {@code format} is {@code null}.
     */
    public PrintWriter printf(String format, Object... args) {
        return format(format, args);
    }

    /**
     * Prints a formatted string. The behavior of this method is the same as
     * this writer's {@code #format(Locale, String, Object...)} method.
     * 
     * @param l
     *            the locale used in the method. No localization will be applied
     *            if {@code l} is {@code null}.
     * @param format
     *            the format string used for {@link java.util.Formatter#format}.
     * @param args
     *            the list of arguments passed to the formatter. If there are
     *            more arguments than required by the {@code format} string,
     *            then the additional arguments are ignored.
     * @return this writer.
     * @throws IllegalFormatException
     *             if the format string is illegal or incompatible with the
     *             arguments, if there are not enough arguments or if any other
     *             error regarding the format string or arguments is detected.
     * @throws NullPointerException
     *             if {@code format} is {@code null}.
     */
    public PrintWriter printf(Locale l, String format, Object... args) {
        return format(l, format, args);
    }

    /**
     * Prints the string representation of the specified character array
     * to the target.
     * 
     * @param charArray
     *            the character array to print to the target.
     * @see #print(String)
     */
    public void print(char[] charArray) {
        print(new String(charArray, 0, charArray.length));
    }

    /**
     * Prints the string representation of the specified character to the
     * target.
     * 
     * @param ch
     *            the character to print to the target.
     * @see #print(String)
     */
    public void print(char ch) {
        print(String.valueOf(ch));
    }

    /**
     * Prints the string representation of the specified double to the target.
     * 
     * @param dnum
     *            the double value to print to the target.
     * @see #print(String)
     */
    public void print(double dnum) {
        print(String.valueOf(dnum));
    }

    /**
     * Prints the string representation of the specified float to the target.
     * 
     * @param fnum
     *            the float value to print to the target.
     * @see #print(String)
     */
    public void print(float fnum) {
        print(String.valueOf(fnum));
    }

    /**
     * Prints the string representation of the specified integer to the target.
     * 
     * @param inum
     *            the integer value to print to the target.
     * @see #print(String)
     */
    public void print(int inum) {
        print(String.valueOf(inum));
    }

    /**
     * Prints the string representation of the specified long to the target.
     * 
     * @param lnum
     *            the long value to print to the target.
     * @see #print(String)
     */
    public void print(long lnum) {
        print(String.valueOf(lnum));
    }

    /**
     * Prints the string representation of the specified object to the target.
     * 
     * @param obj
     *            the object to print to the target.
     * @see #print(String)
     */
    public void print(Object obj) {
        print(String.valueOf(obj));
    }

    /**
     * Prints a string to the target. The string is converted to an array of
     * bytes using the encoding chosen during the construction of this writer.
     * The bytes are then written to the target with {@code write(int)}.
     * <p>
     * If an I/O error occurs, this writer's error flag is set to {@code true}.
     *
     * @param str
     *            the string to print to the target.
     * @see #write(int)
     */
    public void print(String str) {
        write(str != null ? str : String.valueOf((Object) null));
    }

    /**
     * Prints the string representation of the specified boolean to the target.
     * 
     * @param bool
     *            the boolean value to print the target.
     * @see #print(String)
     */
    public void print(boolean bool) {
        print(String.valueOf(bool));
    }

    /**
     * Prints the string representation of the system property {@code
     * "line.separator"} to the target. Flushes this writer if the autoflush
     * flag is set to {@code true}.
     */
    public void println() {
        synchronized (lock) {
            print(lineSeparator);
            if (autoflush) {
                flush();
            }
        }
    }

    /**
     * Prints the string representation of the specified character array
     * followed by the system property {@code "line.separator"} to the target.
     * Flushes this writer if the autoflush flag is set to {@code true}.
     * 
     * @param charArray
     *            the character array to print to the target.
     * @see #print(String)
     */
    public void println(char[] charArray) {
        println(new String(charArray, 0, charArray.length));
    }

    /**
     * Prints the string representation of the specified character followed by
     * the system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param ch
     *            the character to print to the target.
     * @see #print(String)
     */
    public void println(char ch) {
        println(String.valueOf(ch));
    }

    /**
     * Prints the string representation of the specified double followed by the
     * system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param dnum
     *            the double value to print to the target.
     * @see #print(String)
     */
    public void println(double dnum) {
        println(String.valueOf(dnum));
    }

    /**
     * Prints the string representation of the specified float followed by the
     * system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param fnum
     *            the float value to print to the target.
     * @see #print(String)
     */
    public void println(float fnum) {
        println(String.valueOf(fnum));
    }

    /**
     * Prints the string representation of the specified integer followed by the
     * system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param inum
     *            the integer value to print to the target.
     * @see #print(String)
     */
    public void println(int inum) {
        println(String.valueOf(inum));
    }

    /**
     * Prints the string representation of the specified long followed by the
     * system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param lnum
     *            the long value to print to the target.
     * @see #print(String)
     */
    public void println(long lnum) {
        println(String.valueOf(lnum));
    }

    /**
     * Prints the string representation of the specified object followed by the
     * system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param obj
     *            the object to print to the target.
     * @see #print(String)
     */
    public void println(Object obj) {
        println(String.valueOf(obj));
    }

    /**
     * Prints a string followed by the system property {@code "line.separator"}
     * to the target. The string is converted to an array of bytes using the
     * encoding chosen during the construction of this writer. The bytes are
     * then written to the target with {@code write(int)}. Finally, this writer
     * is flushed if the autoflush flag is set to {@code true}.
     * <p>
     * If an I/O error occurs, this writer's error flag is set to {@code true}.
     *
     * @param str
     *            the string to print to the target.
     * @see #write(int)
     */
    public void println(String str) {
        synchronized (lock) {
            print(str);
            println();
        }
    }

    /**
     * Prints the string representation of the specified boolean followed by the
     * system property {@code "line.separator"} to the target. Flushes this
     * writer if the autoflush flag is set to {@code true}.
     * 
     * @param bool
     *            the boolean value to print to the target.
     * @see #print(String)
     */
    public void println(boolean bool) {
        println(String.valueOf(bool));
    }

    /**
     * Sets the error flag of this writer to {@code true}.
     */
    protected void setError() {
        synchronized (lock) {
            ioError = true;
        }
    }

    /**
     * Writes the character buffer {@code buf} to the target.
     * 
     * @param buf
     *            the non-null array containing characters to write.
     */
    @Override
    public void write(char buf[]) {
        write(buf, 0, buf.length);
    }

    /**
     * Writes {@code count} characters from {@code buffer} starting at {@code
     * offset} to the target.
     * <p>
     * This writer's error flag is set to {@code true} if this writer is closed
     * or an I/O error occurs.
     *
     * @param buf
     *            the buffer to write to the target.
     * @param offset
     *            the index of the first character in {@code buffer} to write.
     * @param count
     *            the number of characters in {@code buffer} to write.
     * @throws IndexOutOfBoundsException
     *             if {@code offset < 0} or {@code count < 0}, or if {@code
     *             offset + count} is greater than the length of {@code buf}.
     */
    @Override
    public void write(char buf[], int offset, int count) {
        doWrite(buf, offset, count);
    }

    /**
     * Writes one character to the target. Only the two least significant bytes
     * of the integer {@code oneChar} are written.
     * <p>
     * This writer's error flag is set to {@code true} if this writer is closed
     * or an I/O error occurs.
     * 
     * @param oneChar
     *            the character to write to the target.
     */
    @Override
    public void write(int oneChar) {
        doWrite(new char[] { (char) oneChar }, 0, 1);
    }

    private final void doWrite(char buf[], int offset, int count) {
        synchronized (lock) {
            if (out != null) {
                try {
                    out.write(buf, offset, count);
                } catch (IOException e) {
                    setError();
                }
            } else {
                setError();
            }
        }
    }

    /**
     * Writes the characters from the specified string to the target.
     * 
     * @param str
     *            the non-null string containing the characters to write.
     */
    @Override
    public void write(String str) {
        write(str.toCharArray());
    }

    /**
     * Writes {@code count} characters from {@code str} starting at {@code
     * offset} to the target.
     * 
     * @param str
     *            the non-null string containing the characters to write.
     * @param offset
     *            the index of the first character in {@code str} to write.
     * @param count
     *            the number of characters from {@code str} to write.
     * @throws IndexOutOfBoundsException
     *             if {@code offset < 0} or {@code count < 0}, or if {@code
     *             offset + count} is greater than the length of {@code str}.
     */
    @Override
    public void write(String str, int offset, int count) {
        write(str.substring(offset, offset + count).toCharArray());
    }

    /**
     * Appends the character {@code c} to the target.
     * 
     * @param c
     *            the character to append to the target.
     * @return this writer.
     */
    @Override
    public PrintWriter append(char c) {
        write(c);
        return this;
    }

    /**
     * Appends the character sequence {@code csq} to the target. This
     * method works the same way as {@code PrintWriter.print(csq.toString())}.
     * If {@code csq} is {@code null}, then the string "null" is written
     * to the target.
     * 
     * @param csq
     *            the character sequence appended to the target.
     * @return this writer.
     */
    @Override
    public PrintWriter append(CharSequence csq) {
        if (null == csq) {
            append(TOKEN_NULL, 0, TOKEN_NULL.length());
        } else {
            append(csq, 0, csq.length());
        }
        return this;
    }

    /**
     * Appends a subsequence of the character sequence {@code csq} to the
     * target. This method works the same way as {@code
     * PrintWriter.print(csq.subsequence(start, end).toString())}. If {@code
     * csq} is {@code null}, then the specified subsequence of the string "null"
     * will be written to the target.
     * 
     * @param csq
     *            the character sequence appended to the target.
     * @param start
     *            the index of the first char in the character sequence appended
     *            to the target.
     * @param end
     *            the index of the character following the last character of the
     *            subsequence appended to the target.
     * @return this writer.
     * @throws StringIndexOutOfBoundsException
     *             if {@code start > end}, {@code start < 0}, {@code end < 0} or
     *             either {@code start} or {@code end} are greater or equal than
     *             the length of {@code csq}.
     */
    @Override
    public PrintWriter append(CharSequence csq, int start, int end) {
        if (null == csq) {
            csq = TOKEN_NULL;
        }
        String output = csq.subSequence(start, end).toString();
        write(output, 0, output.length());
        return this;
    }
}
