/*
 * Copyright (C) 2014 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

import okio.ByteString.Companion.decodeHex
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertTrue

/**
 * Tests solely for the behavior of Buffer's implementation. For generic BufferedSink or
 * BufferedSource behavior use BufferedSinkTest or BufferedSourceTest, respectively.
 */
class CommonBufferTest {
  @Test fun readAndWriteUtf8() {
    val buffer = Buffer()
    buffer.writeUtf8("ab")
    assertEquals(2, buffer.size)
    buffer.writeUtf8("cdef")
    assertEquals(6, buffer.size)
    assertEquals("abcd", buffer.readUtf8(4))
    assertEquals(2, buffer.size)
    assertEquals("ef", buffer.readUtf8(2))
    assertEquals(0, buffer.size)
    assertFailsWith<EOFException> {
      buffer.readUtf8(1)
    }
  }

  /** Buffer's toString is the same as ByteString's.  */
  @Test fun bufferToString() {
    assertEquals("[size=0]", Buffer().toString())
    assertEquals(
      "[text=a\\r\\nb\\nc\\rd\\\\e]",
      Buffer().writeUtf8("a\r\nb\nc\rd\\e").toString()
    )
    assertEquals(
      "[text=Tyrannosaur]",
      Buffer().writeUtf8("Tyrannosaur").toString()
    )
    assertEquals(
      "[text=təˈranəˌsôr]",
      Buffer()
        .write("74c999cb8872616ec999cb8c73c3b472".decodeHex())
        .toString()
    )
    assertEquals(
      "[hex=0000000000000000000000000000000000000000000000000000000000000000000000000000" +
        "0000000000000000000000000000000000000000000000000000]",
      Buffer().write(ByteArray(64)).toString()
    )
  }

  @Test fun multipleSegmentBuffers() {
    val buffer = Buffer()
    buffer.writeUtf8('a'.repeat(1000))
    buffer.writeUtf8('b'.repeat(2500))
    buffer.writeUtf8('c'.repeat(5000))
    buffer.writeUtf8('d'.repeat(10000))
    buffer.writeUtf8('e'.repeat(25000))
    buffer.writeUtf8('f'.repeat(50000))

    assertEquals('a'.repeat(999), buffer.readUtf8(999)) // a...a
    assertEquals("a" + 'b'.repeat(2500) + "c", buffer.readUtf8(2502)) // ab...bc
    assertEquals('c'.repeat(4998), buffer.readUtf8(4998)) // c...c
    assertEquals("c" + 'd'.repeat(10000) + "e", buffer.readUtf8(10002)) // cd...de
    assertEquals('e'.repeat(24998), buffer.readUtf8(24998)) // e...e
    assertEquals("e" + 'f'.repeat(50000), buffer.readUtf8(50001)) // ef...f
    assertEquals(0, buffer.size)
  }

  @Test fun fillAndDrainPool() {
    val buffer = Buffer()

    // Take 2 * MAX_SIZE segments. This will drain the pool, even if other tests filled it.
    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
    assertEquals(0, SegmentPool.byteCount)

    // Recycle MAX_SIZE segments. They're all in the pool.
    buffer.skip(SegmentPool.MAX_SIZE.toLong())
    assertEquals(SegmentPool.MAX_SIZE, SegmentPool.byteCount)

    // Recycle MAX_SIZE more segments. The pool is full so they get garbage collected.
    buffer.skip(SegmentPool.MAX_SIZE.toLong())
    assertEquals(SegmentPool.MAX_SIZE, SegmentPool.byteCount)

    // Take MAX_SIZE segments to drain the pool.
    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
    assertEquals(0, SegmentPool.byteCount)

    // Take MAX_SIZE more segments. The pool is drained so these will need to be allocated.
    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
    assertEquals(0, SegmentPool.byteCount)
  }

  @Test fun moveBytesBetweenBuffersShareSegment() {
    val size = Segment.SIZE / 2 - 1
    val segmentSizes = moveBytesBetweenBuffers('a'.repeat(size), 'b'.repeat(size))
    assertEquals(listOf(size * 2), segmentSizes)
  }

  @Test fun moveBytesBetweenBuffersReassignSegment() {
    val size = Segment.SIZE / 2 + 1
    val segmentSizes = moveBytesBetweenBuffers('a'.repeat(size), 'b'.repeat(size))
    assertEquals(listOf(size, size), segmentSizes)
  }

  @Test fun moveBytesBetweenBuffersMultipleSegments() {
    val size = 3 * Segment.SIZE + 1
    val segmentSizes = moveBytesBetweenBuffers('a'.repeat(size), 'b'.repeat(size))
    assertEquals(
      listOf(
        Segment.SIZE, Segment.SIZE, Segment.SIZE, 1,
        Segment.SIZE, Segment.SIZE, Segment.SIZE, 1
      ),
      segmentSizes
    )
  }

  private fun moveBytesBetweenBuffers(vararg contents: String): List<Int> {
    val expected = StringBuilder()
    val buffer = Buffer()
    for (s in contents) {
      val source = Buffer()
      source.writeUtf8(s)
      buffer.writeAll(source)
      expected.append(s)
    }
    val segmentSizes = segmentSizes(buffer)
    assertEquals(expected.toString(), buffer.readUtf8(expected.length.toLong()))
    return segmentSizes
  }

  /** The big part of source's first segment is being moved.  */
  @Test fun writeSplitSourceBufferLeft() {
    val writeSize = Segment.SIZE / 2 + 1

    val sink = Buffer()
    sink.writeUtf8('b'.repeat(Segment.SIZE - 10))

    val source = Buffer()
    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
    sink.write(source, writeSize.toLong())

    assertEquals(listOf(Segment.SIZE - 10, writeSize), segmentSizes(sink))
    assertEquals(listOf(Segment.SIZE - writeSize, Segment.SIZE), segmentSizes(source))
  }

  /** The big part of source's first segment is staying put.  */
  @Test fun writeSplitSourceBufferRight() {
    val writeSize = Segment.SIZE / 2 - 1

    val sink = Buffer()
    sink.writeUtf8('b'.repeat(Segment.SIZE - 10))

    val source = Buffer()
    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
    sink.write(source, writeSize.toLong())

    assertEquals(listOf(Segment.SIZE - 10, writeSize), segmentSizes(sink))
    assertEquals(listOf(Segment.SIZE - writeSize, Segment.SIZE), segmentSizes(source))
  }

  @Test fun writePrefixDoesntSplit() {
    val sink = Buffer()
    sink.writeUtf8('b'.repeat(10))

    val source = Buffer()
    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
    sink.write(source, 20)

    assertEquals(listOf(30), segmentSizes(sink))
    assertEquals(listOf(Segment.SIZE - 20, Segment.SIZE), segmentSizes(source))
    assertEquals(30, sink.size)
    assertEquals((Segment.SIZE * 2 - 20).toLong(), source.size)
  }

  @Test fun writePrefixDoesntSplitButRequiresCompact() {
    val sink = Buffer()
    sink.writeUtf8('b'.repeat(Segment.SIZE - 10)) // limit = size - 10
    sink.readUtf8((Segment.SIZE - 20).toLong()) // pos = size = 20

    val source = Buffer()
    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
    sink.write(source, 20)

    assertEquals(listOf(30), segmentSizes(sink))
    assertEquals(listOf(Segment.SIZE - 20, Segment.SIZE), segmentSizes(source))
    assertEquals(30, sink.size)
    assertEquals((Segment.SIZE * 2 - 20).toLong(), source.size)
  }

  @Test fun moveAllRequestedBytesWithRead() {
    val sink = Buffer()
    sink.writeUtf8('a'.repeat(10))

    val source = Buffer()
    source.writeUtf8('b'.repeat(15))

    assertEquals(10, source.read(sink, 10))
    assertEquals(20, sink.size)
    assertEquals(5, source.size)
    assertEquals('a'.repeat(10) + 'b'.repeat(10), sink.readUtf8(20))
  }

  @Test fun moveFewerThanRequestedBytesWithRead() {
    val sink = Buffer()
    sink.writeUtf8('a'.repeat(10))

    val source = Buffer()
    source.writeUtf8('b'.repeat(20))

    assertEquals(20, source.read(sink, 25))
    assertEquals(30, sink.size)
    assertEquals(0, source.size)
    assertEquals('a'.repeat(10) + 'b'.repeat(20), sink.readUtf8(30))
  }

  @Test fun indexOfWithOffset() {
    val buffer = Buffer()
    val halfSegment = Segment.SIZE / 2
    buffer.writeUtf8('a'.repeat(halfSegment))
    buffer.writeUtf8('b'.repeat(halfSegment))
    buffer.writeUtf8('c'.repeat(halfSegment))
    buffer.writeUtf8('d'.repeat(halfSegment))
    assertEquals(0, buffer.indexOf('a'.toByte(), 0))
    assertEquals((halfSegment - 1).toLong(), buffer.indexOf('a'.toByte(), (halfSegment - 1).toLong()))
    assertEquals(halfSegment.toLong(), buffer.indexOf('b'.toByte(), (halfSegment - 1).toLong()))
    assertEquals((halfSegment * 2).toLong(), buffer.indexOf('c'.toByte(), (halfSegment - 1).toLong()))
    assertEquals((halfSegment * 3).toLong(), buffer.indexOf('d'.toByte(), (halfSegment - 1).toLong()))
    assertEquals((halfSegment * 3).toLong(), buffer.indexOf('d'.toByte(), (halfSegment * 2).toLong()))
    assertEquals((halfSegment * 3).toLong(), buffer.indexOf('d'.toByte(), (halfSegment * 3).toLong()))
    assertEquals((halfSegment * 4 - 1).toLong(), buffer.indexOf('d'.toByte(), (halfSegment * 4 - 1).toLong()))
  }

  @Test fun byteAt() {
    val buffer = Buffer()
    buffer.writeUtf8("a")
    buffer.writeUtf8('b'.repeat(Segment.SIZE))
    buffer.writeUtf8("c")
    assertEquals('a'.toLong(), buffer[0].toLong())
    assertEquals('a'.toLong(), buffer[0].toLong()) // getByte doesn't mutate!
    assertEquals('c'.toLong(), buffer[buffer.size - 1].toLong())
    assertEquals('b'.toLong(), buffer[buffer.size - 2].toLong())
    assertEquals('b'.toLong(), buffer[buffer.size - 3].toLong())
  }

  @Test fun getByteOfEmptyBuffer() {
    val buffer = Buffer()
    assertFailsWith<IndexOutOfBoundsException> {
      buffer[0]
    }
  }

  @Test
  fun writePrefixToEmptyBuffer() {
    val sink = Buffer()
    val source = Buffer()
    source.writeUtf8("abcd")
    sink.write(source, 2)
    assertEquals("ab", sink.readUtf8(2))
  }

  @Suppress("ReplaceAssertBooleanWithAssertEquality")
  @Test fun equalsAndHashCodeEmpty() {
    val a = Buffer()
    val b = Buffer()
    assertTrue(a == b)
    assertTrue(a.hashCode() == b.hashCode())
  }

  @Suppress("ReplaceAssertBooleanWithAssertEquality")
  @Test fun equalsAndHashCode() {
    val a = Buffer().writeUtf8("dog")
    val b = Buffer().writeUtf8("hotdog")
    assertFalse(a == b)
    assertFalse(a.hashCode() == b.hashCode())

    b.readUtf8(3) // Leaves b containing 'dog'.
    assertTrue(a == b)
    assertTrue(a.hashCode() == b.hashCode())
  }

  @Suppress("ReplaceAssertBooleanWithAssertEquality")
  @Test fun equalsAndHashCodeSpanningSegments() {
    val data = ByteArray(1024 * 1024)
    val dice = Random(0)
    dice.nextBytes(data)

    val a = bufferWithRandomSegmentLayout(dice, data)
    val b = bufferWithRandomSegmentLayout(dice, data)
    assertTrue(a == b)
    assertTrue(a.hashCode() == b.hashCode())

    data[data.size / 2]++ // Change a single byte.
    val c = bufferWithRandomSegmentLayout(dice, data)
    assertFalse(a == c)
    assertFalse(a.hashCode() == c.hashCode())
  }

  /**
   * When writing data that's already buffered, there's no reason to page the
   * data by segment.
   */
  @Test fun readAllWritesAllSegmentsAtOnce() {
    val write1 = Buffer().writeUtf8(
      'a'.repeat(Segment.SIZE) +
        'b'.repeat(Segment.SIZE) +
        'c'.repeat(Segment.SIZE)
    )

    val source = Buffer().writeUtf8(
      'a'.repeat(Segment.SIZE) +
        'b'.repeat(Segment.SIZE) +
        'c'.repeat(Segment.SIZE)
    )

    val mockSink = MockSink()

    assertEquals((Segment.SIZE * 3).toLong(), source.readAll(mockSink))
    assertEquals(0, source.size)
    mockSink.assertLog("write($write1, ${write1.size})")
  }

  @Test fun writeAllMultipleSegments() {
    val source = Buffer().writeUtf8('a'.repeat(Segment.SIZE * 3))
    val sink = Buffer()

    assertEquals((Segment.SIZE * 3).toLong(), sink.writeAll(source))
    assertEquals(0, source.size)
    assertEquals('a'.repeat(Segment.SIZE * 3), sink.readUtf8())
  }

  @Test fun copyTo() {
    val source = Buffer()
    source.writeUtf8("party")

    val target = Buffer()
    source.copyTo(target, 1, 3)

    assertEquals("art", target.readUtf8())
    assertEquals("party", source.readUtf8())
  }

  @Test fun copyToOnSegmentBoundary() {
    val `as` = 'a'.repeat(Segment.SIZE)
    val bs = 'b'.repeat(Segment.SIZE)
    val cs = 'c'.repeat(Segment.SIZE)
    val ds = 'd'.repeat(Segment.SIZE)

    val source = Buffer()
    source.writeUtf8(`as`)
    source.writeUtf8(bs)
    source.writeUtf8(cs)

    val target = Buffer()
    target.writeUtf8(ds)

    source.copyTo(target, `as`.length.toLong(), (bs.length + cs.length).toLong())
    assertEquals(ds + bs + cs, target.readUtf8())
  }

  @Test fun copyToOffSegmentBoundary() {
    val `as` = 'a'.repeat(Segment.SIZE - 1)
    val bs = 'b'.repeat(Segment.SIZE + 2)
    val cs = 'c'.repeat(Segment.SIZE - 4)
    val ds = 'd'.repeat(Segment.SIZE + 8)

    val source = Buffer()
    source.writeUtf8(`as`)
    source.writeUtf8(bs)
    source.writeUtf8(cs)

    val target = Buffer()
    target.writeUtf8(ds)

    source.copyTo(target, `as`.length.toLong(), (bs.length + cs.length).toLong())
    assertEquals(ds + bs + cs, target.readUtf8())
  }

  @Test fun copyToSourceAndTargetCanBeTheSame() {
    val `as` = 'a'.repeat(Segment.SIZE)
    val bs = 'b'.repeat(Segment.SIZE)

    val source = Buffer()
    source.writeUtf8(`as`)
    source.writeUtf8(bs)

    source.copyTo(source, 0, source.size)
    assertEquals(`as` + bs + `as` + bs, source.readUtf8())
  }

  @Test fun copyToEmptySource() {
    val source = Buffer()
    val target = Buffer().writeUtf8("aaa")
    source.copyTo(target, 0L, 0L)
    assertEquals("", source.readUtf8())
    assertEquals("aaa", target.readUtf8())
  }

  @Test fun copyToEmptyTarget() {
    val source = Buffer().writeUtf8("aaa")
    val target = Buffer()
    source.copyTo(target, 0L, 3L)
    assertEquals("aaa", source.readUtf8())
    assertEquals("aaa", target.readUtf8())
  }

  @Test fun snapshotReportsAccurateSize() {
    val buf = Buffer().write(byteArrayOf(0, 1, 2, 3))
    assertEquals(1, buf.snapshot(1).size)
  }
}
