/*
 * 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 java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import static java.util.Arrays.asList;
import static okio.TestUtil.repeat;
import static okio.Util.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

@RunWith(Parameterized.class)
public class BufferedSinkTest {
  private interface Factory {
    BufferedSink create(Buffer data);
  }

  // ANDROID-BEGIN
  //  @Parameterized.Parameters(name = "{0}")
  // ANDROID-END
  public static List<Object[]> parameters() {
    return Arrays.asList(new Object[] {
        new Factory() {
          @Override public BufferedSink create(Buffer data) {
            return data;
          }

          @Override public String toString() {
            return "Buffer";
          }
        }
    }, new Object[] {
        new Factory() {
          @Override public BufferedSink create(Buffer data) {
            return new RealBufferedSink(data);
          }

          @Override public String toString() {
            return "RealBufferedSink";
          }
        }
    });
  }

  // ANDROID-BEGIN
  //  @Parameterized.Parameter
  public Factory factory = (Factory) (parameters().get(0))[0];
  // ANDROID-END

  private Buffer data;
  private BufferedSink sink;

  @Before public void setUp() {
    data = new Buffer();
    sink = factory.create(data);
  }

  @Test public void writeNothing() throws IOException {
    sink.writeUtf8("");
    sink.flush();
    assertEquals(0, data.size());
  }

  @Test public void writeBytes() throws Exception {
    sink.writeByte(0xab);
    sink.writeByte(0xcd);
    sink.flush();
    assertEquals("Buffer[size=2 data=abcd]", data.toString());
  }

  @Test public void writeLastByteInSegment() throws Exception {
    sink.writeUtf8(repeat('a', Segment.SIZE - 1));
    sink.writeByte(0x20);
    sink.writeByte(0x21);
    sink.flush();
    assertEquals(asList(Segment.SIZE, 1), data.segmentSizes());
    assertEquals(repeat('a', Segment.SIZE - 1), data.readUtf8(Segment.SIZE - 1));
    assertEquals("Buffer[size=2 data=2021]", data.toString());
  }

  @Test public void writeShort() throws Exception {
    sink.writeShort(0xabcd);
    sink.writeShort(0x4321);
    sink.flush();
    assertEquals("Buffer[size=4 data=abcd4321]", data.toString());
  }

  @Test public void writeShortLe() throws Exception {
    sink.writeShortLe(0xabcd);
    sink.writeShortLe(0x4321);
    sink.flush();
    assertEquals("Buffer[size=4 data=cdab2143]", data.toString());
  }

  @Test public void writeInt() throws Exception {
    sink.writeInt(0xabcdef01);
    sink.writeInt(0x87654321);
    sink.flush();
    assertEquals("Buffer[size=8 data=abcdef0187654321]", data.toString());
  }

  @Test public void writeLastIntegerInSegment() throws Exception {
    sink.writeUtf8(repeat('a', Segment.SIZE - 4));
    sink.writeInt(0xabcdef01);
    sink.writeInt(0x87654321);
    sink.flush();
    assertEquals(asList(Segment.SIZE, 4), data.segmentSizes());
    assertEquals(repeat('a', Segment.SIZE - 4), data.readUtf8(Segment.SIZE - 4));
    assertEquals("Buffer[size=8 data=abcdef0187654321]", data.toString());
  }

  @Test public void writeIntegerDoesNotQuiteFitInSegment() throws Exception {
    sink.writeUtf8(repeat('a', Segment.SIZE - 3));
    sink.writeInt(0xabcdef01);
    sink.writeInt(0x87654321);
    sink.flush();
    assertEquals(asList(Segment.SIZE - 3, 8), data.segmentSizes());
    assertEquals(repeat('a', Segment.SIZE - 3), data.readUtf8(Segment.SIZE - 3));
    assertEquals("Buffer[size=8 data=abcdef0187654321]", data.toString());
  }

  @Test public void writeIntLe() throws Exception {
    sink.writeIntLe(0xabcdef01);
    sink.writeIntLe(0x87654321);
    sink.flush();
    assertEquals("Buffer[size=8 data=01efcdab21436587]", data.toString());
  }

  @Test public void writeLong() throws Exception {
    sink.writeLong(0xabcdef0187654321L);
    sink.writeLong(0xcafebabeb0b15c00L);
    sink.flush();
    assertEquals("Buffer[size=16 data=abcdef0187654321cafebabeb0b15c00]", data.toString());
  }

  @Test public void writeLongLe() throws Exception {
    sink.writeLongLe(0xabcdef0187654321L);
    sink.writeLongLe(0xcafebabeb0b15c00L);
    sink.flush();
    assertEquals("Buffer[size=16 data=2143658701efcdab005cb1b0bebafeca]", data.toString());
  }

  @Test public void writeStringUtf8() throws IOException {
    sink.writeUtf8("təˈranəˌsôr");
    sink.flush();
    assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
  }

  @Test public void writeSubstringUtf8() throws IOException {
    sink.writeUtf8("təˈranəˌsôr", 3, 7);
    sink.flush();
    assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
  }

  @Test public void writeStringWithCharset() throws IOException {
    sink.writeString("təˈranəˌsôr", Charset.forName("utf-32be"));
    sink.flush();
    assertEquals(ByteString.decodeHex("0000007400000259000002c800000072000000610000006e00000259"
        + "000002cc00000073000000f400000072"), data.readByteString());
  }

  @Test public void writeSubstringWithCharset() throws IOException {
    sink.writeString("təˈranəˌsôr", 3, 7, Charset.forName("utf-32be"));
    sink.flush();
    assertEquals(ByteString.decodeHex("00000072000000610000006e00000259"), data.readByteString());
  }

  @Test public void writeAll() throws Exception {
    Buffer source = new Buffer().writeUtf8("abcdef");

    assertEquals(6, sink.writeAll(source));
    assertEquals(0, source.size());
    sink.flush();
    assertEquals("abcdef", data.readUtf8());
  }

  @Test public void writeSource() throws Exception {
    Buffer source = new Buffer().writeUtf8("abcdef");

    // Force resolution of the Source method overload.
    sink.write((Source) source, 4);
    sink.flush();
    assertEquals("abcd", data.readUtf8());
    assertEquals("ef", source.readUtf8());
  }

  @Test public void writeSourceReadsFully() throws Exception {
    Source source = new ForwardingSource(new Buffer()) {
      @Override public long read(Buffer sink, long byteCount) throws IOException {
        sink.writeUtf8("abcd");
        return 4;
      }
    };

    sink.write(source, 8);
    sink.flush();
    assertEquals("abcdabcd", data.readUtf8());
  }

  @Test public void writeSourcePropagatesEof() throws IOException {
    Source source = new Buffer().writeUtf8("abcd");

    try {
      sink.write(source, 8);
      fail();
    } catch (EOFException expected) {
    }

    // Ensure that whatever was available was correctly written.
    sink.flush();
    assertEquals("abcd", data.readUtf8());
  }

  @Test public void writeSourceWithZeroIsNoOp() throws IOException {
    // This test ensures that a zero byte count never calls through to read the source. It may be
    // tied to something like a socket which will potentially block trying to read a segment when
    // ultimately we don't want any data.
    Source source = new ForwardingSource(new Buffer()) {
      @Override public long read(Buffer sink, long byteCount) throws IOException {
        throw new AssertionError();
      }
    };
    sink.write(source, 0);
    assertEquals(0, data.size());
  }

  @Test public void writeAllExhausted() throws Exception {
    Buffer source = new Buffer();
    assertEquals(0, sink.writeAll(source));
    assertEquals(0, source.size());
  }

  @Test public void closeEmitsBufferedBytes() throws IOException {
    sink.writeByte('a');
    sink.close();
    assertEquals('a', data.readByte());
  }

  @Test public void outputStream() throws Exception {
    OutputStream out = sink.outputStream();
    out.write('a');
    out.write(repeat('b', 9998).getBytes(UTF_8));
    out.write('c');
    out.flush();
    assertEquals("a" + repeat('b', 9998) + "c", data.readUtf8());
  }

  @Test public void outputStreamBounds() throws Exception {
    OutputStream out = sink.outputStream();
    try {
      out.write(new byte[100], 50, 51);
      fail();
    } catch (ArrayIndexOutOfBoundsException expected) {
    }
  }

  @Test public void longDecimalString() throws IOException {
    assertLongDecimalString(0);
    assertLongDecimalString(Long.MIN_VALUE);
    assertLongDecimalString(Long.MAX_VALUE);

    for (int i = 1; i < 20; i++) {
      long value = BigInteger.valueOf(10L).pow(i).longValue();
      assertLongDecimalString(value - 1);
      assertLongDecimalString(value);
    }
  }

  private void assertLongDecimalString(long value) throws IOException {
    sink.writeDecimalLong(value).writeUtf8("zzz").flush();
    String expected = Long.toString(value) + "zzz";
    String actual = data.readUtf8();
    assertEquals(value + " expected " + expected + " but was " + actual, actual, expected);
  }

  @Test public void longHexString() throws IOException {
    assertLongHexString(0);
    assertLongHexString(Long.MIN_VALUE);
    assertLongHexString(Long.MAX_VALUE);

    for (int i = 0; i < 16; i++) {
      assertLongHexString((1 << i) - 1);
      assertLongHexString(1 << i);
    }
  }

  private void assertLongHexString(long value) throws IOException {
    sink.writeHexadecimalUnsignedLong(value).writeUtf8("zzz").flush();
    String expected = String.format("%x", value) + "zzz";
    String actual = data.readUtf8();
    assertEquals(value + " expected " + expected + " but was " + actual, actual, expected);
  }
}
