/*
 * Copyright (C) 2019 Square, Inc.
 *
 * 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 okio

/**
 * A source that keeps a buffer internally so that callers can do small reads without a performance
 * penalty. It also allows clients to read ahead, buffering as much as necessary before consuming
 * input.
 */
expect interface BufferedSource : Source {
  /** This source's internal buffer. */
  val buffer: Buffer

  /**
   * Returns true if there are no more bytes in this source. This will block until there are bytes
   * to read or the source is definitely exhausted.
   */
  fun exhausted(): Boolean

  /**
   * Returns when the buffer contains at least `byteCount` bytes. Throws an
   * [java.io.EOFException] if the source is exhausted before the required bytes can be read.
   */
  fun require(byteCount: Long)

  /**
   * Returns true when the buffer contains at least `byteCount` bytes, expanding it as
   * necessary. Returns false if the source is exhausted before the requested bytes can be read.
   */
  fun request(byteCount: Long): Boolean

  /** Removes a byte from this source and returns it. */
  fun readByte(): Byte

  /**
   * Removes two bytes from this source and returns a big-endian short.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeByte(0x7f)
   *     .writeByte(0xff)
   *     .writeByte(0x00)
   *     .writeByte(0x0f);
   * assertEquals(4, buffer.size());
   *
   * assertEquals(32767, buffer.readShort());
   * assertEquals(2, buffer.size());
   *
   * assertEquals(15, buffer.readShort());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readShort(): Short

  /**
   * Removes two bytes from this source and returns a little-endian short.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeByte(0xff)
   *     .writeByte(0x7f)
   *     .writeByte(0x0f)
   *     .writeByte(0x00);
   * assertEquals(4, buffer.size());
   *
   * assertEquals(32767, buffer.readShortLe());
   * assertEquals(2, buffer.size());
   *
   * assertEquals(15, buffer.readShortLe());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readShortLe(): Short

  /**
   * Removes four bytes from this source and returns a big-endian int.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeByte(0x7f)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x0f);
   * assertEquals(8, buffer.size());
   *
   * assertEquals(2147483647, buffer.readInt());
   * assertEquals(4, buffer.size());
   *
   * assertEquals(15, buffer.readInt());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readInt(): Int

  /**
   * Removes four bytes from this source and returns a little-endian int.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0x7f)
   *     .writeByte(0x0f)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00);
   * assertEquals(8, buffer.size());
   *
   * assertEquals(2147483647, buffer.readIntLe());
   * assertEquals(4, buffer.size());
   *
   * assertEquals(15, buffer.readIntLe());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readIntLe(): Int

  /**
   * Removes eight bytes from this source and returns a big-endian long.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeByte(0x7f)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x0f);
   * assertEquals(16, buffer.size());
   *
   * assertEquals(9223372036854775807L, buffer.readLong());
   * assertEquals(8, buffer.size());
   *
   * assertEquals(15, buffer.readLong());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readLong(): Long

  /**
   * Removes eight bytes from this source and returns a little-endian long.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0xff)
   *     .writeByte(0x7f)
   *     .writeByte(0x0f)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00)
   *     .writeByte(0x00);
   * assertEquals(16, buffer.size());
   *
   * assertEquals(9223372036854775807L, buffer.readLongLe());
   * assertEquals(8, buffer.size());
   *
   * assertEquals(15, buffer.readLongLe());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readLongLe(): Long

  /**
   * Reads a long from this source in signed decimal form (i.e., as a string in base 10 with
   * optional leading '-'). This will iterate until a non-digit character is found.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeUtf8("8675309 -123 00001");
   *
   * assertEquals(8675309L, buffer.readDecimalLong());
   * assertEquals(' ', buffer.readByte());
   * assertEquals(-123L, buffer.readDecimalLong());
   * assertEquals(' ', buffer.readByte());
   * assertEquals(1L, buffer.readDecimalLong());
   * ```
   *
   * @throws NumberFormatException if the found digits do not fit into a `long` or a decimal
   * number was not present.
   */
  fun readDecimalLong(): Long

  /**
   * Reads a long form this source in hexadecimal form (i.e., as a string in base 16). This will
   * iterate until a non-hexadecimal character is found.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeUtf8("ffff CAFEBABE 10");
   *
   * assertEquals(65535L, buffer.readHexadecimalUnsignedLong());
   * assertEquals(' ', buffer.readByte());
   * assertEquals(0xcafebabeL, buffer.readHexadecimalUnsignedLong());
   * assertEquals(' ', buffer.readByte());
   * assertEquals(0x10L, buffer.readHexadecimalUnsignedLong());
   * ```
   *
   * @throws NumberFormatException if the found hexadecimal does not fit into a `long` or
   * hexadecimal was not found.
   */
  fun readHexadecimalUnsignedLong(): Long

  /**
   * Reads and discards `byteCount` bytes from this source. Throws an [java.io.EOFException] if the
   * source is exhausted before the requested bytes can be skipped.
   */
  fun skip(byteCount: Long)

  /** Removes all bytes from this and returns them as a byte string. */
  fun readByteString(): ByteString

  /** Removes `byteCount` bytes from this and returns them as a byte string. */
  fun readByteString(byteCount: Long): ByteString

  /**
   * Finds the first string in `options` that is a prefix of this buffer, consumes it from this
   * buffer, and returns its index. If no byte string in `options` is a prefix of this buffer this
   * returns -1 and no bytes are consumed.
   *
   * This can be used as an alternative to [readByteString] or even [readUtf8] if the set of
   * expected values is known in advance.
   * ```
   * Options FIELDS = Options.of(
   *     ByteString.encodeUtf8("depth="),
   *     ByteString.encodeUtf8("height="),
   *     ByteString.encodeUtf8("width="));
   *
   * Buffer buffer = new Buffer()
   *     .writeUtf8("width=640\n")
   *     .writeUtf8("height=480\n");
   *
   * assertEquals(2, buffer.select(FIELDS));
   * assertEquals(640, buffer.readDecimalLong());
   * assertEquals('\n', buffer.readByte());
   * assertEquals(1, buffer.select(FIELDS));
   * assertEquals(480, buffer.readDecimalLong());
   * assertEquals('\n', buffer.readByte());
   * ```
   */
  fun select(options: Options): Int

  /** Removes all bytes from this and returns them as a byte array. */
  fun readByteArray(): ByteArray

  /** Removes `byteCount` bytes from this and returns them as a byte array. */
  fun readByteArray(byteCount: Long): ByteArray

  /**
   * Removes up to `sink.length` bytes from this and copies them into `sink`. Returns the number of
   * bytes read, or -1 if this source is exhausted.
   */
  fun read(sink: ByteArray): Int

  /**
   * Removes exactly `sink.length` bytes from this and copies them into `sink`. Throws an
   * [java.io.EOFException] if the requested number of bytes cannot be read.
   */
  fun readFully(sink: ByteArray)

  /**
   * Removes up to `byteCount` bytes from this and copies them into `sink` at `offset`. Returns the
   * number of bytes read, or -1 if this source is exhausted.
   */
  fun read(sink: ByteArray, offset: Int, byteCount: Int): Int

  /**
   * Removes exactly `byteCount` bytes from this and appends them to `sink`. Throws an
   * [java.io.EOFException] if the requested number of bytes cannot be read.
   */
  fun readFully(sink: Buffer, byteCount: Long)

  /**
   * Removes all bytes from this and appends them to `sink`. Returns the total number of bytes
   * written to `sink` which will be 0 if this is exhausted.
   */
  fun readAll(sink: Sink): Long

  /**
   * Removes all bytes from this, decodes them as UTF-8, and returns the string. Returns the empty
   * string if this source is empty.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeUtf8("Uh uh uh!")
   *     .writeByte(' ')
   *     .writeUtf8("You didn't say the magic word!");
   *
   * assertEquals("Uh uh uh! You didn't say the magic word!", buffer.readUtf8());
   * assertEquals(0, buffer.size());
   *
   * assertEquals("", buffer.readUtf8());
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readUtf8(): String

  /**
   * Removes `byteCount` bytes from this, decodes them as UTF-8, and returns the string.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeUtf8("Uh uh uh!")
   *     .writeByte(' ')
   *     .writeUtf8("You didn't say the magic word!");
   * assertEquals(40, buffer.size());
   *
   * assertEquals("Uh uh uh! You ", buffer.readUtf8(14));
   * assertEquals(26, buffer.size());
   *
   * assertEquals("didn't say the", buffer.readUtf8(14));
   * assertEquals(12, buffer.size());
   *
   * assertEquals(" magic word!", buffer.readUtf8(12));
   * assertEquals(0, buffer.size());
   * ```
   */
  fun readUtf8(byteCount: Long): String

  /**
   * Removes and returns characters up to but not including the next line break. A line break is
   * either `"\n"` or `"\r\n"`; these characters are not included in the result.
   * ```
   * Buffer buffer = new Buffer()
   *     .writeUtf8("I'm a hacker!\n")
   *     .writeUtf8("That's what I said: you're a nerd.\n")
   *     .writeUtf8("I prefer to be called a hacker!\n");
   * assertEquals(81, buffer.size());
   *
   * assertEquals("I'm a hacker!", buffer.readUtf8Line());
   * assertEquals(67, buffer.size());
   *
   * assertEquals("That's what I said: you're a nerd.", buffer.readUtf8Line());
   * assertEquals(32, buffer.size());
   *
   * assertEquals("I prefer to be called a hacker!", buffer.readUtf8Line());
   * assertEquals(0, buffer.size());
   *
   * assertEquals(null, buffer.readUtf8Line());
   * assertEquals(0, buffer.size());
   * ```
   *
   * **On the end of the stream this method returns null,** just like [java.io.BufferedReader]. If
   * the source doesn't end with a line break then an implicit line break is assumed. Null is
   * returned once the source is exhausted. Use this for human-generated data, where a trailing
   * line break is optional.
   */
  fun readUtf8Line(): String?

  /**
   * Removes and returns characters up to but not including the next line break. A line break is
   * either `"\n"` or `"\r\n"`; these characters are not included in the result.
   *
   * **On the end of the stream this method throws.** Every call must consume either
   * '\r\n' or '\n'. If these characters are absent in the stream, an [java.io.EOFException]
   * is thrown. Use this for machine-generated data where a missing line break implies truncated
   * input.
   */
  fun readUtf8LineStrict(): String

  /**
   * Like [readUtf8LineStrict], except this allows the caller to specify the longest allowed match.
   * Use this to protect against streams that may not include `"\n"` or `"\r\n"`.
   *
   * The returned string will have at most `limit` UTF-8 bytes, and the maximum number of bytes
   * scanned is `limit + 2`. If `limit == 0` this will always throw an `EOFException` because no
   * bytes will be scanned.
   *
   * This method is safe. No bytes are discarded if the match fails, and the caller is free to try
   * another match:
   * ```
   * Buffer buffer = new Buffer();
   * buffer.writeUtf8("12345\r\n");
   *
   * // This will throw! There must be \r\n or \n at the limit or before it.
   * buffer.readUtf8LineStrict(4);
   *
   * // No bytes have been consumed so the caller can retry.
   * assertEquals("12345", buffer.readUtf8LineStrict(5));
   * ```
   */
  fun readUtf8LineStrict(limit: Long): String

  /**
   * Removes and returns a single UTF-8 code point, reading between 1 and 4 bytes as necessary.
   *
   * If this source is exhausted before a complete code point can be read, this throws an
   * [java.io.EOFException] and consumes no input.
   *
   * If this source doesn't start with a properly-encoded UTF-8 code point, this method will remove
   * 1 or more non-UTF-8 bytes and return the replacement character (`U+FFFD`). This covers encoding
   * problems (the input is not properly-encoded UTF-8), characters out of range (beyond the
   * 0x10ffff limit of Unicode), code points for UTF-16 surrogates (U+d800..U+dfff) and overlong
   * encodings (such as `0xc080` for the NUL character in modified UTF-8).
   */
  fun readUtf8CodePoint(): Int

  /** Equivalent to [indexOf(b, 0)][indexOf]. */
  fun indexOf(b: Byte): Long

  /**
   * Returns the index of the first `b` in the buffer at or after `fromIndex`. This expands the
   * buffer as necessary until `b` is found. This reads an unbounded number of bytes into the
   * buffer. Returns -1 if the stream is exhausted before the requested byte is found.
   * ```
   * Buffer buffer = new Buffer();
   * buffer.writeUtf8("Don't move! He can't see us if we don't move.");
   *
   * byte m = 'm';
   * assertEquals(6,  buffer.indexOf(m));
   * assertEquals(40, buffer.indexOf(m, 12));
   * ```
   */
  fun indexOf(b: Byte, fromIndex: Long): Long

  /**
   * Returns the index of `b` if it is found in the range of `fromIndex` inclusive to `toIndex`
   * exclusive. If `b` isn't found, or if `fromIndex == toIndex`, then -1 is returned.
   *
   * The scan terminates at either `toIndex` or the end of the buffer, whichever comes first. The
   * maximum number of bytes scanned is `toIndex-fromIndex`.
   */
  fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long

  /** Equivalent to [indexOf(bytes, 0)][indexOf]. */
  fun indexOf(bytes: ByteString): Long

  /**
   * Returns the index of the first match for `bytes` in the buffer at or after `fromIndex`. This
   * expands the buffer as necessary until `bytes` is found. This reads an unbounded number of
   * bytes into the buffer. Returns -1 if the stream is exhausted before the requested bytes are
   * found.
   * ```
   * ByteString MOVE = ByteString.encodeUtf8("move");
   *
   * Buffer buffer = new Buffer();
   * buffer.writeUtf8("Don't move! He can't see us if we don't move.");
   *
   * assertEquals(6,  buffer.indexOf(MOVE));
   * assertEquals(40, buffer.indexOf(MOVE, 12));
   * ```
   */
  fun indexOf(bytes: ByteString, fromIndex: Long): Long

  /** Equivalent to [indexOfElement(targetBytes, 0)][indexOfElement]. */
  fun indexOfElement(targetBytes: ByteString): Long

  /**
   * Returns the first index in this buffer that is at or after `fromIndex` and that contains any of
   * the bytes in `targetBytes`. This expands the buffer as necessary until a target byte is found.
   * This reads an unbounded number of bytes into the buffer. Returns -1 if the stream is exhausted
   * before the requested byte is found.
   * ```
   * ByteString ANY_VOWEL = ByteString.encodeUtf8("AEOIUaeoiu");
   *
   * Buffer buffer = new Buffer();
   * buffer.writeUtf8("Dr. Alan Grant");
   *
   * assertEquals(4,  buffer.indexOfElement(ANY_VOWEL));    // 'A' in 'Alan'.
   * assertEquals(11, buffer.indexOfElement(ANY_VOWEL, 9)); // 'a' in 'Grant'.
   * ```
   */
  fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long

  /**
   * Returns true if the bytes at `offset` in this source equal `bytes`. This expands the buffer as
   * necessary until a byte does not match, all bytes are matched, or if the stream is exhausted
   * before enough bytes could determine a match.
   * ```
   * ByteString simonSays = ByteString.encodeUtf8("Simon says:");
   *
   * Buffer standOnOneLeg = new Buffer().writeUtf8("Simon says: Stand on one leg.");
   * assertTrue(standOnOneLeg.rangeEquals(0, simonSays));
   *
   * Buffer payMeMoney = new Buffer().writeUtf8("Pay me $1,000,000.");
   * assertFalse(payMeMoney.rangeEquals(0, simonSays));
   * ```
   */
  fun rangeEquals(offset: Long, bytes: ByteString): Boolean

  /**
   * Returns true if `byteCount` bytes at `offset` in this source equal `bytes` at `bytesOffset`.
   * This expands the buffer as necessary until a byte does not match, all bytes are matched, or if
   * the stream is exhausted before enough bytes could determine a match.
   */
  fun rangeEquals(offset: Long, bytes: ByteString, bytesOffset: Int, byteCount: Int): Boolean

  /**
   * Returns a new `BufferedSource` that can read data from this `BufferedSource` without consuming
   * it. The returned source becomes invalid once this source is next read or closed.
   *
   * For example, we can use `peek()` to lookahead and read the same data multiple times.
   *
   * ```
   * val buffer = Buffer()
   * buffer.writeUtf8("abcdefghi")
   *
   * buffer.readUtf8(3) // returns "abc", buffer contains "defghi"
   *
   * val peek = buffer.peek()
   * peek.readUtf8(3) // returns "def", buffer contains "defghi"
   * peek.readUtf8(3) // returns "ghi", buffer contains "defghi"
   *
   * buffer.readUtf8(3) // returns "def", buffer contains "ghi"
   * ```
   */
  fun peek(): BufferedSource
}
