// Copyright (C) 2009 The Android Open Source Project
//
// 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.gerrit.server.ioutil;

import static com.google.gerrit.server.ioutil.BasicSerialization.readFixInt64;
import static com.google.gerrit.server.ioutil.BasicSerialization.readString;
import static com.google.gerrit.server.ioutil.BasicSerialization.readVarInt32;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeFixInt64;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeString;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeVarInt32;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import com.google.gerrit.testing.GerritBaseTests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;

public class BasicSerializationTest extends GerritBaseTests {
  @Test
  public void testReadVarInt32() throws IOException {
    assertEquals(0x00000000, readVarInt32(r(b(0))));
    assertEquals(0x00000003, readVarInt32(r(b(3))));
    assertEquals(0x000000ff, readVarInt32(r(b(0x80 | 0x7f, 0x01))));
  }

  @Test
  public void testWriteVarInt32() throws IOException {
    ByteArrayOutputStream out;

    out = new ByteArrayOutputStream();
    writeVarInt32(out, 0);
    assertOutput(b(0), out);

    out = new ByteArrayOutputStream();
    writeVarInt32(out, 3);
    assertOutput(b(3), out);

    out = new ByteArrayOutputStream();
    writeVarInt32(out, 0xff);
    assertOutput(b(0x80 | 0x7f, 0x01), out);
  }

  @Test
  public void testReadFixInt64() throws IOException {
    assertEquals(0L, readFixInt64(r(b(0, 0, 0, 0, 0, 0, 0, 0))));
    assertEquals(3L, readFixInt64(r(b(0, 0, 0, 0, 0, 0, 0, 3))));

    assertEquals(0xdeadbeefL, readFixInt64(r(b(0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef))));

    assertEquals(0x0310adefL, readFixInt64(r(b(0, 0, 0, 0, 0x03, 0x10, 0xad, 0xef))));

    assertEquals(
        0xc0ffee78deadbeefL, readFixInt64(r(b(0xc0, 0xff, 0xee, 0x78, 0xde, 0xad, 0xbe, 0xef))));

    assertEquals(0x00000000ffffffffL, readFixInt64(r(b(0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff))));

    assertEquals(
        0xffffffffffffffffL, readFixInt64(r(b(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff))));
  }

  @Test
  public void testWriteFixInt64() throws IOException {
    ByteArrayOutputStream out;

    out = new ByteArrayOutputStream(8);
    writeFixInt64(out, 0L);
    assertOutput(b(0, 0, 0, 0, 0, 0, 0, 0), out);

    out = new ByteArrayOutputStream(8);
    writeFixInt64(out, 3L);
    assertOutput(b(0, 0, 0, 0, 0, 0, 0, 3), out);

    out = new ByteArrayOutputStream(8);
    writeFixInt64(out, 0xdeacL);
    assertOutput(b(0, 0, 0, 0, 0, 0, 0xde, 0xac), out);

    out = new ByteArrayOutputStream(8);
    writeFixInt64(out, 0xdeac9853L);
    assertOutput(b(0, 0, 0, 0, 0xde, 0xac, 0x98, 0x53), out);

    out = new ByteArrayOutputStream(8);
    writeFixInt64(out, 0xac431242deac9853L);
    assertOutput(b(0xac, 0x43, 0x12, 0x42, 0xde, 0xac, 0x98, 0x53), out);

    out = new ByteArrayOutputStream(8);
    writeFixInt64(out, -1L);
    assertOutput(b(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), out);
  }

  @Test
  public void testReadString() throws IOException {
    assertNull(readString(r(b(0))));
    assertEquals("a", readString(r(b(1, 'a'))));
    assertEquals("coffee4", readString(r(b(7, 'c', 'o', 'f', 'f', 'e', 'e', '4'))));
  }

  @Test
  public void testWriteString() throws IOException {
    ByteArrayOutputStream out;

    out = new ByteArrayOutputStream();
    writeString(out, null);
    assertOutput(b(0), out);

    out = new ByteArrayOutputStream();
    writeString(out, "");
    assertOutput(b(0), out);

    out = new ByteArrayOutputStream();
    writeString(out, "a");
    assertOutput(b(1, 'a'), out);

    out = new ByteArrayOutputStream();
    writeString(out, "coffee4");
    assertOutput(b(7, 'c', 'o', 'f', 'f', 'e', 'e', '4'), out);
  }

  private static void assertOutput(byte[] expect, ByteArrayOutputStream out) {
    final byte[] buf = out.toByteArray();
    for (int i = 0; i < expect.length; i++) {
      assertEquals(expect[i], buf[i]);
    }
  }

  private static InputStream r(byte[] buf) {
    return new ByteArrayInputStream(buf);
  }

  private static byte[] b(int a) {
    return new byte[] {(byte) a};
  }

  private static byte[] b(int a, int b) {
    return new byte[] {(byte) a, (byte) b};
  }

  private static byte[] b(int a, int b, int c, int d, int e, int f, int g, int h) {
    return new byte[] {
      (byte) a, (byte) b, (byte) c, (byte) d, //
      (byte) e, (byte) f, (byte) g, (byte) h,
    };
  }
}
