/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed 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 com.google.common.io;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndexes;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;

/**
 * Provides utility methods for working with character streams.
 *
 * <p>All method parameters must be non-null unless documented otherwise.
 *
 * <p>Some of the methods in this class take arguments with a generic type of {@code Readable &
 * Closeable}. A {@link java.io.Reader} implements both of those interfaces. Similarly for {@code
 * Appendable & Closeable} and {@link java.io.Writer}.
 *
 * @author Chris Nokleberg
 * @author Bin Zhu
 * @author Colin Decker
 * @since 1.0
 */
@GwtIncompatible
public final class CharStreams {

  // 2K chars (4K bytes)
  private static final int DEFAULT_BUF_SIZE = 0x800;

  /** Creates a new {@code CharBuffer} for buffering reads or writes. */
  static CharBuffer createBuffer() {
    return CharBuffer.allocate(DEFAULT_BUF_SIZE);
  }

  private CharStreams() {}

  /**
   * Copies all characters between the {@link Readable} and {@link Appendable} objects. Does not
   * close or flush either object.
   *
   * @param from the object to read from
   * @param to the object to write to
   * @return the number of characters copied
   * @throws IOException if an I/O error occurs
   */
  @CanIgnoreReturnValue
  public static long copy(Readable from, Appendable to) throws IOException {
    // The most common case is that from is a Reader (like InputStreamReader or StringReader) so
    // take advantage of that.
    if (from instanceof Reader) {
      // optimize for common output types which are optimized to deal with char[]
      if (to instanceof StringBuilder) {
        return copyReaderToBuilder((Reader) from, (StringBuilder) to);
      } else {
        return copyReaderToWriter((Reader) from, asWriter(to));
      }
    } else {
      checkNotNull(from);
      checkNotNull(to);
      long total = 0;
      CharBuffer buf = createBuffer();
      while (from.read(buf) != -1) {
        Java8Compatibility.flip(buf);
        to.append(buf);
        total += buf.remaining();
        Java8Compatibility.clear(buf);
      }
      return total;
    }
  }

  // TODO(lukes): consider allowing callers to pass in a buffer to use, some callers would be able
  // to reuse buffers, others would be able to size them more appropriately than the constant
  // defaults

  /**
   * Copies all characters between the {@link Reader} and {@link StringBuilder} objects. Does not
   * close or flush the reader.
   *
   * <p>This is identical to {@link #copy(Readable, Appendable)} but optimized for these specific
   * types. CharBuffer has poor performance when being written into or read out of so round tripping
   * all the bytes through the buffer takes a long time. With these specialized types we can just
   * use a char array.
   *
   * @param from the object to read from
   * @param to the object to write to
   * @return the number of characters copied
   * @throws IOException if an I/O error occurs
   */
  @CanIgnoreReturnValue
  static long copyReaderToBuilder(Reader from, StringBuilder to) throws IOException {
    checkNotNull(from);
    checkNotNull(to);
    char[] buf = new char[DEFAULT_BUF_SIZE];
    int nRead;
    long total = 0;
    while ((nRead = from.read(buf)) != -1) {
      to.append(buf, 0, nRead);
      total += nRead;
    }
    return total;
  }

  /**
   * Copies all characters between the {@link Reader} and {@link Writer} objects. Does not close or
   * flush the reader or writer.
   *
   * <p>This is identical to {@link #copy(Readable, Appendable)} but optimized for these specific
   * types. CharBuffer has poor performance when being written into or read out of so round tripping
   * all the bytes through the buffer takes a long time. With these specialized types we can just
   * use a char array.
   *
   * @param from the object to read from
   * @param to the object to write to
   * @return the number of characters copied
   * @throws IOException if an I/O error occurs
   */
  @CanIgnoreReturnValue
  static long copyReaderToWriter(Reader from, Writer to) throws IOException {
    checkNotNull(from);
    checkNotNull(to);
    char[] buf = new char[DEFAULT_BUF_SIZE];
    int nRead;
    long total = 0;
    while ((nRead = from.read(buf)) != -1) {
      to.write(buf, 0, nRead);
      total += nRead;
    }
    return total;
  }

  /**
   * Reads all characters from a {@link Readable} object into a {@link String}. Does not close the
   * {@code Readable}.
   *
   * @param r the object to read from
   * @return a string containing all the characters
   * @throws IOException if an I/O error occurs
   */
  public static String toString(Readable r) throws IOException {
    return toStringBuilder(r).toString();
  }

  /**
   * Reads all characters from a {@link Readable} object into a new {@link StringBuilder} instance.
   * Does not close the {@code Readable}.
   *
   * @param r the object to read from
   * @return a {@link StringBuilder} containing all the characters
   * @throws IOException if an I/O error occurs
   */
  private static StringBuilder toStringBuilder(Readable r) throws IOException {
    StringBuilder sb = new StringBuilder();
    if (r instanceof Reader) {
      copyReaderToBuilder((Reader) r, sb);
    } else {
      copy(r, sb);
    }
    return sb;
  }

  /**
   * Reads all of the lines from a {@link Readable} object. The lines do not include
   * line-termination characters, but do include other leading and trailing whitespace.
   *
   * <p>Does not close the {@code Readable}. If reading files or resources you should use the {@link
   * Files#readLines} and {@link Resources#readLines} methods.
   *
   * @param r the object to read from
   * @return a mutable {@link List} containing all the lines
   * @throws IOException if an I/O error occurs
   */
  @Beta
  public static List<String> readLines(Readable r) throws IOException {
    List<String> result = new ArrayList<>();
    LineReader lineReader = new LineReader(r);
    String line;
    while ((line = lineReader.readLine()) != null) {
      result.add(line);
    }
    return result;
  }

  /**
   * Streams lines from a {@link Readable} object, stopping when the processor returns {@code false}
   * or all lines have been read and returning the result produced by the processor. Does not close
   * {@code readable}. Note that this method may not fully consume the contents of {@code readable}
   * if the processor stops processing early.
   *
   * @throws IOException if an I/O error occurs
   * @since 14.0
   */
  @Beta
  @CanIgnoreReturnValue // some processors won't return a useful result
  public static <T> T readLines(Readable readable, LineProcessor<T> processor) throws IOException {
    checkNotNull(readable);
    checkNotNull(processor);

    LineReader lineReader = new LineReader(readable);
    String line;
    while ((line = lineReader.readLine()) != null) {
      if (!processor.processLine(line)) {
        break;
      }
    }
    return processor.getResult();
  }

  /**
   * Reads and discards data from the given {@code Readable} until the end of the stream is reached.
   * Returns the total number of chars read. Does not close the stream.
   *
   * @since 20.0
   */
  @Beta
  @CanIgnoreReturnValue
  public static long exhaust(Readable readable) throws IOException {
    long total = 0;
    long read;
    CharBuffer buf = createBuffer();
    while ((read = readable.read(buf)) != -1) {
      total += read;
      Java8Compatibility.clear(buf);
    }
    return total;
  }

  /**
   * Discards {@code n} characters of data from the reader. This method will block until the full
   * amount has been skipped. Does not close the reader.
   *
   * @param reader the reader to read from
   * @param n the number of characters to skip
   * @throws EOFException if this stream reaches the end before skipping all the characters
   * @throws IOException if an I/O error occurs
   */
  @Beta
  public static void skipFully(Reader reader, long n) throws IOException {
    checkNotNull(reader);
    while (n > 0) {
      long amt = reader.skip(n);
      if (amt == 0) {
        throw new EOFException();
      }
      n -= amt;
    }
  }

  /**
   * Returns a {@link Writer} that simply discards written chars.
   *
   * @since 15.0
   */
  @Beta
  public static Writer nullWriter() {
    return NullWriter.INSTANCE;
  }

  private static final class NullWriter extends Writer {

    private static final NullWriter INSTANCE = new NullWriter();

    @Override
    public void write(int c) {}

    @Override
    public void write(char[] cbuf) {
      checkNotNull(cbuf);
    }

    @Override
    public void write(char[] cbuf, int off, int len) {
      checkPositionIndexes(off, off + len, cbuf.length);
    }

    @Override
    public void write(String str) {
      checkNotNull(str);
    }

    @Override
    public void write(String str, int off, int len) {
      checkPositionIndexes(off, off + len, str.length());
    }

    @Override
    public Writer append(@NullableDecl CharSequence csq) {
      return this;
    }

    @Override
    public Writer append(@NullableDecl CharSequence csq, int start, int end) {
      checkPositionIndexes(start, end, csq == null ? "null".length() : csq.length());
      return this;
    }

    @Override
    public Writer append(char c) {
      return this;
    }

    @Override
    public void flush() {}

    @Override
    public void close() {}

    @Override
    public String toString() {
      return "CharStreams.nullWriter()";
    }
  }

  /**
   * Returns a Writer that sends all output to the given {@link Appendable} target. Closing the
   * writer will close the target if it is {@link Closeable}, and flushing the writer will flush the
   * target if it is {@link java.io.Flushable}.
   *
   * @param target the object to which output will be sent
   * @return a new Writer object, unless target is a Writer, in which case the target is returned
   */
  @Beta
  public static Writer asWriter(Appendable target) {
    if (target instanceof Writer) {
      return (Writer) target;
    }
    return new AppendableWriter(target);
  }
}
