/*
 * 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.phoenix.schema.types;

import java.sql.Types;
import java.text.Format;

import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.StringUtil;

import com.google.common.base.Preconditions;

public class PVarchar extends PDataType<String> {

  public static final PVarchar INSTANCE = new PVarchar();

  private PVarchar() {
    super("VARCHAR", Types.VARCHAR, String.class, null, 0);
  }

  @Override
  public byte[] toBytes(Object object) {
    // TODO: consider using avro UTF8 object instead of String
    // so that we get get the size easily
    if (object == null) {
      return ByteUtil.EMPTY_BYTE_ARRAY;
    }
    return Bytes.toBytes((String) object);
  }

  @Override
  public int toBytes(Object object, byte[] bytes, int offset) {
    if (object == null) {
      return 0;
    }
    byte[] b = toBytes(object); // TODO: no byte[] allocation: use CharsetEncoder
    System.arraycopy(b, 0, bytes, offset, b.length);
    return b.length;
  }

  @Override
  public Object toObject(byte[] bytes, int offset, int length, PDataType actualType,
      SortOrder sortOrder, Integer maxLength, Integer scale) {
    if (length == 0) {
      return null;
    }
    if (!actualType.isCoercibleTo(this)) {
      throwConstraintViolationException(actualType, this);
    }
    if (sortOrder == SortOrder.DESC) {
      bytes = SortOrder.invert(bytes, offset, length);
      offset = 0;
    }
    return Bytes.toString(bytes, offset, length);
  }

  @Override
  public Object toObject(Object object, PDataType actualType) {
    if (equalsAny(actualType, this, PChar.INSTANCE)) {
      String s = (String) object;
      return s == null || s.length() > 0 ? s : null;
    }
    return throwConstraintViolationException(actualType, this);
  }

  @Override
  public boolean isCoercibleTo(PDataType targetType) {
    return equalsAny(targetType, this, PChar.INSTANCE, PVarbinary.INSTANCE, PBinary.INSTANCE);
  }

  @Override
  public boolean isCoercibleTo(PDataType targetType, Object value) {
    if (isCoercibleTo(targetType)) {
      if (targetType.equals(PChar.INSTANCE)) {
        return value != null;
      }
      return true;
    }
    return false;
  }

  @Override
  public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value, PDataType srcType,
      Integer maxLength, Integer scale, Integer desiredMaxLength,
      Integer desiredScale) {
    if (ptr.getLength() != 0 && maxLength != null && desiredMaxLength != null) {
      return maxLength <= desiredMaxLength;
    }
    return true;
  }

  @Override
  public boolean isFixedWidth() {
    return false;
  }

  @Override
  public int estimateByteSize(Object o) {
    String value = (String) o;
    return value == null ? 1 : value.length();
  }

  @Override
  public Integer getByteSize() {
    return null;
  }

  @Override
  public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
    return ((String) lhs).compareTo((String) rhs);
  }

  @Override
  public Object toObject(String value) {
    return value;
  }

  @Override
  public boolean isBytesComparableWith(PDataType otherType) {
    return super.isBytesComparableWith(otherType) || otherType == PChar.INSTANCE;
  }

  @Override
  public String toStringLiteral(Object o, Format formatter) {
    if (formatter != null) {
      return "'" + formatter.format(o) + "'";
    }
    return null == o ? String.valueOf(o) : "'" + StringUtil.escapeStringConstant(o.toString()) + "'";
  }

  private char[] sampleChars = new char[1];

  @Override
  public Object getSampleValue(Integer maxLength, Integer arrayLength) {
    Preconditions.checkArgument(maxLength == null || maxLength >= 0);
    int length = maxLength != null ? maxLength : 1;
    if (length != sampleChars.length) {
      sampleChars = new char[length];
    }
    for (int i = 0; i < length; i++) {
      sampleChars[i] = (char) RANDOM.get().nextInt(Byte.MAX_VALUE);
    }
    return new String(sampleChars);
  }
}
