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

#include "value.hpp"

#include "collection_iterator.hpp"
#include "data_type.hpp"
#include "external.hpp"
#include "serialization.hpp"

#define CHECK_RESULT(result) \
  if (!(result)) return false;
#define CHECK_VALUE(result)                  \
  do {                                       \
    if ((result)) {                          \
      return CASS_OK;                        \
    } else {                                 \
      return CASS_ERROR_LIB_NOT_ENOUGH_DATA; \
    }                                        \
  } while (0)

using namespace datastax;
using namespace datastax::internal;
using namespace datastax::internal::core;

extern "C" {

const CassDataType* cass_value_data_type(const CassValue* value) {
  return CassDataType::to(value->data_type().get());
}

CassError cass_value_get_int8(const CassValue* value, cass_int8_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_TINY_INT) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_int8(output));
}

CassError cass_value_get_int16(const CassValue* value, cass_int16_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_SMALL_INT) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_int16(output));
}

CassError cass_value_get_int32(const CassValue* value, cass_int32_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_INT) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_int32(output));
}

CassError cass_value_get_uint32(const CassValue* value, cass_uint32_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_DATE) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_uint32(output));
}

CassError cass_value_get_int64(const CassValue* value, cass_int64_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (!is_int64_type(value->value_type())) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_int64(output));
}

CassError cass_value_get_float(const CassValue* value, cass_float_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_FLOAT) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_float(output));
}

CassError cass_value_get_double(const CassValue* value, cass_double_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_DOUBLE) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_double(output));
}

CassError cass_value_get_bool(const CassValue* value, cass_bool_t* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_BOOLEAN) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  bool decode_value = false;
  if (!value->decoder().as_bool(&decode_value)) {
    return CASS_ERROR_LIB_NOT_ENOUGH_DATA;
  }
  *output = decode_value ? cass_true : cass_false;
  return CASS_OK;
}

CassError cass_value_get_uuid(const CassValue* value, CassUuid* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (!is_uuid_type(value->value_type())) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_uuid(output));
}

CassError cass_value_get_inet(const CassValue* value, CassInet* output) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_INET) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  if (!value->decoder().as_inet(value->size(), output)) {
    return CASS_ERROR_LIB_INVALID_DATA;
  }
  return CASS_OK;
}

CassError cass_value_get_string(const CassValue* value, const char** output,
                                size_t* output_length) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  StringRef buffer = value->decoder().as_string_ref();
  *output = buffer.data();
  *output_length = buffer.size();
  return CASS_OK;
}

CassError cass_value_get_bytes(const CassValue* value, const cass_byte_t** output,
                               size_t* output_size) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  StringRef buffer = value->decoder().as_string_ref();
  *output = reinterpret_cast<const cass_byte_t*>(buffer.data());
  *output_size = buffer.size();
  return CASS_OK;
}

CassError cass_value_get_duration(const CassValue* value, cass_int32_t* months, cass_int32_t* days,
                                  cass_int64_t* nanos) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (!cass_value_is_duration(value)) return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  CHECK_VALUE(value->decoder().as_duration(months, days, nanos));
}

CassError cass_value_get_decimal(const CassValue* value, const cass_byte_t** varint,
                                 size_t* varint_size, cass_int32_t* scale) {
  if (value == NULL || value->is_null()) return CASS_ERROR_LIB_NULL_VALUE;
  if (value->value_type() != CASS_VALUE_TYPE_DECIMAL) {
    return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
  }
  CHECK_VALUE(value->decoder().as_decimal(varint, varint_size, scale));
}

CassValueType cass_value_type(const CassValue* value) { return value->value_type(); }

cass_bool_t cass_value_is_null(const CassValue* value) {
  return static_cast<cass_bool_t>(value->is_null());
}

cass_bool_t cass_value_is_collection(const CassValue* value) {
  return static_cast<cass_bool_t>(value->is_collection());
}

cass_bool_t cass_value_is_duration(const CassValue* value) {
  IsValidDataType<CassDuration> is_valid;
  CassDuration dummy(0, 0, 0);
  return static_cast<cass_bool_t>(is_valid(dummy, value->data_type()));
}

size_t cass_value_item_count(const CassValue* collection) { return collection->count(); }

CassValueType cass_value_primary_sub_type(const CassValue* collection) {
  return collection->primary_value_type();
}

CassValueType cass_value_secondary_sub_type(const CassValue* collection) {
  return collection->secondary_value_type();
}

} // extern "C"

Value::Value(const DataType::ConstPtr& data_type, Decoder decoder)
    : data_type_(data_type)
    , count_(0)
    , decoder_(decoder)
    , is_null_(false) {
  assert(!data_type->is_collection());
  if (data_type->is_tuple()) {
    const CompositeType& composite_type = static_cast<const CompositeType&>(*data_type);
    count_ = composite_type.types().size();
  } else if (data_type->is_user_type()) {
    const UserType& user_type = static_cast<const UserType&>(*data_type);
    count_ = user_type.fields().size();
  }
}

bool Value::update(const Decoder& decoder) {
  decoder_ = decoder;
  is_null_ = decoder_.is_null();
  if (!is_null_) {
    if (data_type_->is_collection()) {
      return decoder_.decode_int32(count_);
    } else if (data_type_->is_tuple()) {
      const CompositeType& composite_type = static_cast<const CompositeType&>(*data_type_);
      count_ = composite_type.types().size();
    } else if (data_type_->is_user_type()) {
      const UserType& user_type = static_cast<const UserType&>(*data_type_);
      count_ = user_type.fields().size();
    }
  } else {
    count_ = 0;
  }
  return true;
}

bool Value::as_bool() const {
  assert(!is_null() && value_type() == CASS_VALUE_TYPE_BOOLEAN);
  bool value = false;
  bool result = decoder_.as_bool(&value);
  UNUSED_(result);
  assert(result);
  return value;
}

int32_t Value::as_int32() const {
  assert(!is_null() && value_type() == CASS_VALUE_TYPE_INT);
  int32_t value = 0;
  bool result = decoder_.as_int32(&value);
  UNUSED_(result);
  assert(result);
  return value;
}

CassUuid Value::as_uuid() const {
  assert(!is_null() &&
         (value_type() == CASS_VALUE_TYPE_UUID || value_type() == CASS_VALUE_TYPE_TIMEUUID));
  CassUuid value = { 0, 0 };
  bool result = decoder_.as_uuid(&value);
  UNUSED_(result);
  assert(result);
  return value;
}

StringVec Value::as_stringlist() const {
  assert(!is_null() &&
         (value_type() == CASS_VALUE_TYPE_LIST || value_type() == CASS_VALUE_TYPE_SET) &&
         primary_value_type() == CASS_VALUE_TYPE_VARCHAR);
  StringVec stringlist;
  CollectionIterator iterator(this);
  while (iterator.next()) {
    stringlist.push_back(iterator.value()->to_string());
  }
  return stringlist;
}
