/**
 * Copyright The Apache Software Foundation
 *
 * 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.hbase;

import java.nio.ByteBuffer;

import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;

/**
 * This is a {@link Tag} implementation in which value is backed by an on heap byte array.
 */
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class ArrayBackedTag implements Tag {
  private final byte type;// TODO  extra type state needed?
  private final byte[] bytes;
  private int offset = 0;
  private int length = 0;

  /**
   * The special tag will write the length of each tag and that will be
   * followed by the type and then the actual tag.
   * So every time the length part is parsed we need to add + 1 byte to it to
   * get the type and then get the actual tag.
   */
  public ArrayBackedTag(byte tagType, String tag) {
    this(tagType, Bytes.toBytes(tag));
  }

  /**
   * Format for a tag :
   * {@code <length of tag - 2 bytes><type code - 1 byte><tag>} tag length is serialized
   * using 2 bytes only but as this will be unsigned, we can have max tag length of
   * (Short.MAX_SIZE * 2) +1. It includes 1 byte type length and actual tag bytes length.
   */
  public ArrayBackedTag(byte tagType, byte[] tag) {
    int tagLength = tag.length + TYPE_LENGTH_SIZE;
    if (tagLength > MAX_TAG_LENGTH) {
      throw new IllegalArgumentException(
          "Invalid tag data being passed. Its length can not exceed " + MAX_TAG_LENGTH);
    }
    length = TAG_LENGTH_SIZE + tagLength;
    bytes = new byte[length];
    int pos = Bytes.putAsShort(bytes, 0, tagLength);
    pos = Bytes.putByte(bytes, pos, tagType);
    Bytes.putBytes(bytes, pos, tag, 0, tag.length);
    this.type = tagType;
  }

  /**
   * Creates a Tag from the specified byte array and offset. Presumes
   * <code>bytes</code> content starting at <code>offset</code> is formatted as
   * a Tag blob.
   * The bytes to include the tag type, tag length and actual tag bytes.
   * @param offset offset to start of Tag
   */
  public ArrayBackedTag(byte[] bytes, int offset) {
    this(bytes, offset, getLength(bytes, offset));
  }

  private static int getLength(byte[] bytes, int offset) {
    return TAG_LENGTH_SIZE + Bytes.readAsInt(bytes, offset, TAG_LENGTH_SIZE);
  }

  /**
   * Creates a Tag from the specified byte array, starting at offset, and for length
   * <code>length</code>. Presumes <code>bytes</code> content starting at <code>offset</code> is
   * formatted as a Tag blob.
   */
  public ArrayBackedTag(byte[] bytes, int offset, int length) {
    if (length > MAX_TAG_LENGTH) {
      throw new IllegalArgumentException(
          "Invalid tag data being passed. Its length can not exceed " + MAX_TAG_LENGTH);
    }
    this.bytes = bytes;
    this.offset = offset;
    this.length = length;
    this.type = bytes[offset + TAG_LENGTH_SIZE];
  }

  /**
   * @return The byte array backing this Tag.
   */
  @Override
  public byte[] getValueArray() {
    return this.bytes;
  }

  /**
   * @return the tag type
   */
  @Override
  public byte getType() {
    return this.type;
  }

  /**
   * @return Length of actual tag bytes within the backed buffer
   */
  @Override
  public int getValueLength() {
    return this.length - INFRASTRUCTURE_SIZE;
  }

  /**
   * @return Offset of actual tag bytes within the backed buffer
   */
  @Override
  public int getValueOffset() {
    return this.offset + INFRASTRUCTURE_SIZE;
  }

  @Override
  public boolean hasArray() {
    return true;
  }

  @Override
  public ByteBuffer getValueByteBuffer() {
    return ByteBuffer.wrap(bytes);
  }

  @Override
  public String toString() {
    return "[Tag type : " + this.type + ", value : "
        + Bytes.toStringBinary(bytes, getValueOffset(), getValueLength()) + "]";
  }
}
