/**
 * 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.record;

import java.io.UnsupportedEncodingException;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

/**
 * A byte sequence that is used as a Java native type for buffer.
 * It is resizable and distinguishes between the count of the sequence and
 * the current capacity.
 * 
 * @deprecated Replaced by <a href="http://avro.apache.org/">Avro</a>.
 */
@Deprecated
@InterfaceAudience.Public
@InterfaceStability.Stable
public class Buffer implements Comparable, Cloneable {
  /** Number of valid bytes in this.bytes. */
  private int count;
  /** Backing store for Buffer. */
  private byte[] bytes = null;

  /**
   * Create a zero-count sequence.
   */
  public Buffer() {
    this.count = 0;
  }

  /**
   * Create a Buffer using the byte array as the initial value.
   *
   * @param bytes This array becomes the backing storage for the object.
   */
  public Buffer(byte[] bytes) {
    this.bytes = bytes;
    this.count = (bytes == null) ? 0 : bytes.length;
  }
  
  /**
   * Create a Buffer using the byte range as the initial value.
   *
   * @param bytes Copy of this array becomes the backing storage for the object.
   * @param offset offset into byte array
   * @param length length of data
   */
  public Buffer(byte[] bytes, int offset, int length) {
    copy(bytes, offset, length);
  }
  
  
  /**
   * Use the specified bytes array as underlying sequence.
   *
   * @param bytes byte sequence
   */
  public void set(byte[] bytes) {
    this.count = (bytes == null) ? 0 : bytes.length;
    this.bytes = bytes;
  }
  
  /**
   * Copy the specified byte array to the Buffer. Replaces the current buffer.
   *
   * @param bytes byte array to be assigned
   * @param offset offset into byte array
   * @param length length of data
   */
  public final void copy(byte[] bytes, int offset, int length) {
    if (this.bytes == null || this.bytes.length < length) {
      this.bytes = new byte[length];
    }
    System.arraycopy(bytes, offset, this.bytes, 0, length);
    this.count = length;
  }
  
  /**
   * Get the data from the Buffer.
   * 
   * @return The data is only valid between 0 and getCount() - 1.
   */
  public byte[] get() {
    if (bytes == null) {
      bytes = new byte[0];
    }
    return bytes;
  }
  
  /**
   * Get the current count of the buffer.
   */
  public int getCount() {
    return count;
  }
  
  /**
   * Get the capacity, which is the maximum count that could handled without
   * resizing the backing storage.
   * 
   * @return The number of bytes
   */
  public int getCapacity() {
    return this.get().length;
  }
  
  /**
   * Change the capacity of the backing storage.
   * The data is preserved if newCapacity {@literal >=} getCount().
   * @param newCapacity The new capacity in bytes.
   */
  public void setCapacity(int newCapacity) {
    if (newCapacity < 0) {
      throw new IllegalArgumentException("Invalid capacity argument "+newCapacity); 
    }
    if (newCapacity == 0) {
      this.bytes = null;
      this.count = 0;
      return;
    }
    if (newCapacity != getCapacity()) {
      byte[] data = new byte[newCapacity];
      if (newCapacity < count) {
        count = newCapacity;
      }
      if (count != 0) {
        System.arraycopy(this.get(), 0, data, 0, count);
      }
      bytes = data;
    }
  }
  
  /**
   * Reset the buffer to 0 size
   */
  public void reset() {
    setCapacity(0);
  }
  
  /**
   * Change the capacity of the backing store to be the same as the current 
   * count of buffer.
   */
  public void truncate() {
    setCapacity(count);
  }

  /**
   * Append specified bytes to the buffer.
   *
   * @param bytes byte array to be appended
   * @param offset offset into byte array
   * @param length length of data

  */
  public void append(byte[] bytes, int offset, int length) {
    setCapacity(count+length);
    System.arraycopy(bytes, offset, this.get(), count, length);
    count = count + length;
  }
  
  /**
   * Append specified bytes to the buffer
   *
   * @param bytes byte array to be appended
   */
  public void append(byte[] bytes) {
    append(bytes, 0, bytes.length);
  }
  
  // inherit javadoc
  @Override
  public int hashCode() {
    int hash = 1;
    byte[] b = this.get();
    for (int i = 0; i < count; i++)
      hash = (31 * hash) + b[i];
    return hash;
  }
  
  /**
   * Define the sort order of the Buffer.
   * 
   * @param other The other buffer
   * @return Positive if this is bigger than other, 0 if they are equal, and
   *         negative if this is smaller than other.
   */
  @Override
  public int compareTo(Object other) {
    Buffer right = ((Buffer) other);
    byte[] lb = this.get();
    byte[] rb = right.get();
    for (int i = 0; i < count && i < right.count; i++) {
      int a = (lb[i] & 0xff);
      int b = (rb[i] & 0xff);
      if (a != b) {
        return a - b;
      }
    }
    return count - right.count;
  }
  
  // inherit javadoc
  @Override
  public boolean equals(Object other) {
    if (other instanceof Buffer && this != other) {
      return compareTo(other) == 0;
    }
    return (this == other);
  }
  
  // inheric javadoc
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(2*count);
    for(int idx = 0; idx < count; idx++) {
      sb.append(Character.forDigit((bytes[idx] & 0xF0) >> 4, 16));
      sb.append(Character.forDigit(bytes[idx] & 0x0F, 16));
    }
    return sb.toString();
  }
  
  /**
   * Convert the byte buffer to a string an specific character encoding
   *
   * @param charsetName Valid Java Character Set Name
   */
  public String toString(String charsetName)
    throws UnsupportedEncodingException {
    return new String(this.get(), 0, this.getCount(), charsetName);
  }
  
  // inherit javadoc
  @Override
  public Object clone() throws CloneNotSupportedException {
    Buffer result = (Buffer) super.clone();
    result.copy(this.get(), 0, this.getCount());
    return result;
  }
}
