/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.hadoop.io.file.tfile;

import java.io.IOException;
import java.util.Random;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class TestVLong extends TestCase {
  private static String ROOT =
      System.getProperty("test.build.data", "/tmp/tfile-test");
  private Configuration conf;
  private FileSystem fs;
  private Path path;
  private String outputFile = "TestVLong";

  @Override
  public void setUp() throws IOException {
    conf = new Configuration();
    path = new Path(ROOT, outputFile);
    fs = path.getFileSystem(conf);
    if (fs.exists(path)) {
      fs.delete(path, false);
    }
  }

  @Override
  public void tearDown() throws IOException {
    if (fs.exists(path)) {
      fs.delete(path, false);
    }
  }

  public void testVLongByte() throws IOException {
    FSDataOutputStream out = fs.create(path);
    for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; ++i) {
      Utils.writeVLong(out, i);
    }
    out.close();
    Assert.assertEquals("Incorrect encoded size", (1 << Byte.SIZE) + 96, fs
        .getFileStatus(
        path).getLen());

    FSDataInputStream in = fs.open(path);
    for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; ++i) {
      long n = Utils.readVLong(in);
      Assert.assertEquals(n, i);
    }
    in.close();
    fs.delete(path, false);
  }

  private long writeAndVerify(int shift) throws IOException {
    FSDataOutputStream out = fs.create(path);
    for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; ++i) {
      Utils.writeVLong(out, ((long) i) << shift);
    }
    out.close();
    FSDataInputStream in = fs.open(path);
    for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; ++i) {
      long n = Utils.readVLong(in);
      Assert.assertEquals(n, ((long) i) << shift);
    }
    in.close();
    long ret = fs.getFileStatus(path).getLen();
    fs.delete(path, false);
    return ret;
  }
  
  public void testVLongShort() throws IOException {
    long size = writeAndVerify(0);
    Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 2
        + ((1 << Byte.SIZE) - 40)
        * (1 << Byte.SIZE) - 128 - 32, size);
  }

  public void testVLong3Bytes() throws IOException {
    long size = writeAndVerify(Byte.SIZE);
    Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 3
        + ((1 << Byte.SIZE) - 32) * (1 << Byte.SIZE) - 40 - 1, size);
  }

  public void testVLong4Bytes() throws IOException {
    long size = writeAndVerify(Byte.SIZE * 2);
    Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 4
        + ((1 << Byte.SIZE) - 16) * (1 << Byte.SIZE) - 32 - 2, size);
  }

  public void testVLong5Bytes() throws IOException {
    long size = writeAndVerify(Byte.SIZE * 3);
     Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 6 - 256
        - 16 - 3, size);
  }

  private void verifySixOrMoreBytes(int bytes) throws IOException {
    long size = writeAndVerify(Byte.SIZE * (bytes - 2));
    Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE)
        * (bytes + 1) - 256 - bytes + 1, size);
  }
  public void testVLong6Bytes() throws IOException {
    verifySixOrMoreBytes(6);
  }
  
  public void testVLong7Bytes() throws IOException {
    verifySixOrMoreBytes(7);
  }

  public void testVLong8Bytes() throws IOException {
    verifySixOrMoreBytes(8);
  }

  public void testVLongRandom() throws IOException {
    int count = 1024 * 1024;
    long data[] = new long[count];
    Random rng = new Random();
    for (int i = 0; i < data.length; ++i) {
      int shift = rng.nextInt(Long.SIZE) + 1;
      long mask = (1L << shift) - 1;
      long a = ((long) rng.nextInt()) << 32;
      long b = ((long) rng.nextInt()) & 0xffffffffL;
      data[i] = (a + b) & mask;
    }
    
    FSDataOutputStream out = fs.create(path);
    for (int i = 0; i < data.length; ++i) {
      Utils.writeVLong(out, data[i]);
    }
    out.close();

    FSDataInputStream in = fs.open(path);
    for (int i = 0; i < data.length; ++i) {
      Assert.assertEquals(Utils.readVLong(in), data[i]);
    }
    in.close();
    fs.delete(path, false);
  }
}
