// Copyright 2010 Google 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 com.google.gwtorm.nosql;


import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;

/**
 * Encoder support for {@link IndexFunction} computed strings.
 * <p>
 * This class provides a string that may contain multiple values, using
 * delimiters between fields and big-endian encoded numerics. Sorting the
 * resulting strings using unsigned byte orderings produces a stable sorting.
 * <p>
 * The encoding used by this class relies on having 258 tokens. To get the extra
 * 2 tokens within a 256 byte range, escapes are used according to the following
 * simple table:
 * <ul>
 * <li>delimiter = \x00\x01
 * <li>byte \x00 = \x00\xff
 * <li>byte \xff = \xff\x00
 * <li>infinity = \xff\xff
 * </ul>
 * <p>
 * Integers are encoded as variable length big-endian values, skipping leading
 * zero bytes, prefixed by the number of bytes used to encode them. Therefore 0
 * is encoded as "\x00", and 256 is encoded as "\x02\x01\x00". Negative values
 * are encoded in their twos complement encoding and therefore sort after the
 * maximum positive value.
 * <p>
 * Strings and byte arrays supplied by the caller have their \x00 and \xff
 * values escaped according to the table above, but are otherwise written as-is
 * without a length prefix.
 * <p>
 * Callers are responsible for inserting {@link #delimiter()} markers at the
 * appropriate positions in the sequence.
 */
public class IndexKeyBuilder {
  private final ByteArrayOutputStream buf = new ByteArrayOutputStream();

  /**
   * Add a delimiter marker to the string.
   */
  public void delimiter() {
    buf.write(0x00);
    buf.write(0x01);
  }

  /**
   * Add the special infinity symbol to the string.
   * <p>
   * The infinity symbol sorts after all other values in the same position.
   */
  public void infinity() {
    buf.write(0xff);
    buf.write(0xff);
  }

  /**
   * Add \0 to the string.
   * <p>
   * \0 can be used during searches to enforce greater then or less then clauses
   * in a query.
   */
  public void nul() {
    buf.write(0x00);
  }

  /**
   * Add a raw sequence of bytes.
   * <p>
   * The bytes 0x00 and 0xff are escaped by this method according to the
   * encoding table described in the class documentation.
   *
   * @param bin array to copy from.
   * @param pos first index to copy.
   * @param cnt number of bytes to copy.
   */
  public void add(byte[] bin, int pos, int cnt) {
    while (0 < cnt--) {
      byte b = bin[pos++];
      if (b == 0x00) {
        buf.write(0x00);
        buf.write(0xff);

      } else if (b == -1) {
        buf.write(0xff);
        buf.write(0x00);

      } else {
        buf.write(b);
      }
    }
  }

  public void desc(byte[] bin, int pos, int cnt) {
    while (0 < cnt--) {
      int b = 0xff - (bin[pos++] & 0xff);
      if (b == 0x00) {
        buf.write(0x00);
        buf.write(0xff);

      } else if (b == 0xff) {
        buf.write(0xff);
        buf.write(0x00);

      } else {
        buf.write(b);
      }
    }
  }

  /**
   * Add a raw sequence of bytes.
   * <p>
   * The bytes 0x00 and 0xff are escaped by this method according to the
   * encoding table described in the class documentation.
   *
   * @param bin the complete array to copy.
   */
  public void add(byte[] bin) {
    add(bin, 0, bin.length);
  }

  public void desc(byte[] bin) {
    desc(bin, 0, bin.length);
  }

  /**
   * Encode a string into UTF-8 and append as a sequence of bytes.
   *
   * @param str the string to encode and append.
   */
  public void add(String str) {
    try {
      add(str.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("JVM does not support UTF-8", e);
    }
  }

  public void desc(String str) {
    try {
      desc(str.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("JVM does not support UTF-8", e);
    }
  }

  /**
   * Add a single character as though it were part of a UTF-8 string.
   *
   * @param ch the character to encode and append.
   */
  public void add(char ch) {
    if (ch == 0x00) {
      buf.write(0x00);
      buf.write(0xff);

    } else if (ch <= 255) {
      buf.write(ch);

    } else {
      add(Character.toString(ch));
    }
  }

  public void desc(char ch) {
    desc(Character.toString(ch));
  }

  /**
   * Add an integer value as a big-endian variable length integer.
   *
   * @param val the value to add.
   */
  public void add(long val) {
    final byte[] t = new byte[9];
    int i = t.length;
    while (val != 0) {
      t[--i] = (byte) (val & 0xff);
      val >>>= 8;
    }
    t[i - 1] = (byte) (t.length - i);
    buf.write(t, i - 1, t.length - i + 1);
  }

  public void desc(long val) {
    add(~val);
  }

  /**
   * Add a byte array as-is, without escaping.
   * <p>
   * This should only be used the byte array came from a prior index key and the
   * caller is trying to create a new key with this key embedded at the end.
   *
   * @param bin the binary to append as-is, without further escaping.
   */
  public void addRaw(byte[] bin) {
    buf.write(bin, 0, bin.length);
  }

  /**
   * Obtain a copy of the internal storage array.
   *
   * @return the current state of this, converted into a flat byte array.
   */
  public byte[] toByteArray() {
    return buf.toByteArray();
  }
}
