// 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 "exprs/slot-ref.h"

#include <limits>
#include <sstream>

#include "codegen/codegen-anyval.h"
#include "codegen/llvm-codegen.h"
#include "exprs/scalar-expr-evaluator.h"
#include "gen-cpp/Exprs_types.h"
#include "runtime/collection-value.h"
#include "runtime/decimal-value.h"
#include "runtime/multi-precision.h"
#include "runtime/runtime-state.h"
#include "runtime/string-value.inline.h"
#include "runtime/timestamp-value.h"
#include "runtime/tuple-row.h"

#include "common/names.h"

using namespace impala_udf;

namespace impala {

const char* SlotRef::LLVM_CLASS_NAME = "class.impala::SlotRef";

SlotRef::SlotRef(const TExprNode& node)
  : ScalarExpr(node),
    slot_offset_(-1),  // invalid
    null_indicator_offset_(0, 0),
    slot_id_(node.slot_ref.slot_id) {
    // slot_/null_indicator_offset_ are set in Prepare()
}

SlotRef::SlotRef(const SlotDescriptor* desc)
  : ScalarExpr(desc->type(), false),
    slot_offset_(-1),
    null_indicator_offset_(0, 0),
    slot_id_(desc->id()) {
    // slot_/null_indicator_offset_ are set in Prepare()
}

SlotRef::SlotRef(const SlotDescriptor* desc, const ColumnType& type)
  : ScalarExpr(type, false),
    slot_offset_(-1),
    null_indicator_offset_(0, 0),
    slot_id_(desc->id()) {
    // slot_/null_indicator_offset_ are set in Prepare()
}

SlotRef::SlotRef(const ColumnType& type, int offset, const bool nullable /* = false */)
  : ScalarExpr(type, false),
    tuple_idx_(0),
    slot_offset_(offset),
    null_indicator_offset_(0, nullable ? offset : -1),
    slot_id_(-1) {}

Status SlotRef::Init(
    const RowDescriptor& row_desc, bool is_entry_point, RuntimeState* state) {
  DCHECK_EQ(children_.size(), 0);
  RETURN_IF_ERROR(ScalarExpr::Init(row_desc, is_entry_point, state));
  if (slot_id_ != -1) {
    const SlotDescriptor* slot_desc = state->desc_tbl().GetSlotDescriptor(slot_id_);
    if (slot_desc == NULL) {
      // TODO: create macro MAKE_ERROR() that returns a stream
      stringstream error;
      error << "couldn't resolve slot descriptor " << slot_id_;
      LOG(INFO) << error.str();
      return Status(error.str());
    }
    tuple_idx_ = row_desc.GetTupleIdx(slot_desc->parent()->id());
    if (tuple_idx_ == RowDescriptor::INVALID_IDX) {
      TupleDescriptor* d =
          state->desc_tbl().GetTupleDescriptor(slot_desc->parent()->id());
      string error = Substitute("invalid tuple_idx: $0\nparent=$1\nrow=$2",
          slot_desc->DebugString(), d->DebugString(), row_desc.DebugString());
      LOG(INFO) << error;
      return Status(error);
    }
    DCHECK(tuple_idx_ != RowDescriptor::INVALID_IDX);
    tuple_is_nullable_ = row_desc.TupleIsNullable(tuple_idx_);
    slot_offset_ = slot_desc->tuple_offset();
    null_indicator_offset_ = slot_desc->null_indicator_offset();
  }
  return Status::OK();
}

int SlotRef::GetSlotIds(vector<SlotId>* slot_ids) const {
  if (slot_ids != nullptr) slot_ids->push_back(slot_id_);
  return 1;
}

string SlotRef::DebugString() const {
  stringstream out;
  out << "SlotRef(slot_id=" << slot_id_
      << " tuple_idx=" << tuple_idx_ << " slot_offset=" << slot_offset_
      << " tuple_is_nullable=" << tuple_is_nullable_
      << " null_indicator=" << null_indicator_offset_
      << ScalarExpr::DebugString() << ")";
  return out.str();
}

// There are four possible cases we may generate:
//   1. Tuple is non-nullable and slot is non-nullable
//   2. Tuple is non-nullable and slot is nullable
//   3. Tuple is nullable and slot is non-nullable (when the aggregate output is the
//      "nullable" side of an outer join).
//   4. Tuple is nullable and slot is nullable
//
// Resulting IR for a bigint slotref:
// (Note: some of the GEPs that look like no-ops are because certain offsets are 0
// in this slot descriptor.)
//
// define { i8, i64 } @GetSlotRef(i8** %context, %"class.impala::TupleRow"* %row) {
// entry:
//   %cast_row_ptr = bitcast %"class.impala::TupleRow"* %row to i8**
//   %tuple_addr = getelementptr i8** %cast_row_ptr, i32 0
//   %tuple_ptr = load i8** %tuple_addr
//   br label %check_slot_null
//
// check_slot_null:                                  ; preds = %entry
//   %null_byte_ptr = getelementptr i8* %tuple_ptr, i32 0
//   %null_byte = load i8* %null_ptr
//   %null_byte_set = and i8 %null_byte, 2
//   %is_null = icmp ne i8 %null_byte_set, 0
//   br i1 %is_null, label %ret, label %get_slot
//
// get_slot:                                         ; preds = %check_slot_null
//   %slot_addr = getelementptr i8* %tuple_ptr, i32 8
//   %val_ptr = bitcast i8* %slot_addr to i64*
//   %val = load i64* %val_ptr
//   br label %ret
//
// ret:                                              ; preds = %get_slot, %check_slot_null
//   %is_null_phi = phi i8 [ 1, %check_slot_null ], [ 0, %get_slot ]
//   %val_phi = phi i64 [ 0, %check_slot_null ], [ %val, %get_slot ]
//   %result = insertvalue { i8, i64 } zeroinitializer, i8 %is_null_phi, 0
//   %result1 = insertvalue { i8, i64 } %result, i64 %val_phi, 1
//   ret { i8, i64 } %result1
// }
//
// TODO: We could generate a typed struct (and not a char*) for Tuple for llvm.  We know
// the types from the TupleDesc.  It will likely make this code simpler to reason about.
Status SlotRef::GetCodegendComputeFnImpl(LlvmCodeGen* codegen, llvm::Function** fn) {
  DCHECK_EQ(GetNumChildren(), 0);
  // SlotRefs are based on the slot_id and tuple_idx.  Combine them to make a
  // query-wide unique id. We also need to combine whether the tuple is nullable. For
  // example, in an outer join the scan node could have the same tuple id and slot id
  // as the join node. When the slot is being used in the scan-node, the tuple is
  // non-nullable. Used in the join node (and above in the plan tree), it is nullable.
  // TODO: can we do something better.
  constexpr int64_t TUPLE_NULLABLE_MASK = numeric_limits<int64_t>::min();
  int64_t unique_slot_id = slot_id_ | ((int64_t)tuple_idx_) << 32;
  DCHECK_EQ(unique_slot_id & TUPLE_NULLABLE_MASK, 0);
  if (tuple_is_nullable_) unique_slot_id |= TUPLE_NULLABLE_MASK;
  llvm::Function* ir_compute_fn_ = codegen->GetRegisteredExprFn(unique_slot_id);
  if (ir_compute_fn_ != NULL) {
    *fn = ir_compute_fn_;
    return Status::OK();
  }

  llvm::LLVMContext& context = codegen->context();
  llvm::Value* args[2];
  *fn = CreateIrFunctionPrototype("GetSlotRef", codegen, &args);
  llvm::Value* row_ptr = args[1];

  llvm::Value* tuple_offset = codegen->GetI32Constant(tuple_idx_);
  llvm::Value* slot_offset = codegen->GetI32Constant(slot_offset_);
  llvm::Value* zero = codegen->GetI8Constant(0);
  llvm::Value* one = codegen->GetI8Constant(1);

  llvm::BasicBlock* entry_block = llvm::BasicBlock::Create(context, "entry", *fn);
  bool slot_is_nullable = null_indicator_offset_.bit_mask != 0;
  llvm::BasicBlock* check_slot_null_indicator_block = NULL;
  if (slot_is_nullable) {
    check_slot_null_indicator_block =
        llvm::BasicBlock::Create(context, "check_slot_null", *fn);
  }
  llvm::BasicBlock* get_slot_block = llvm::BasicBlock::Create(context, "get_slot", *fn);
  llvm::BasicBlock* ret_block = llvm::BasicBlock::Create(context, "ret", *fn);

  LlvmBuilder builder(entry_block);
  // Get the tuple offset addr from the row
  llvm::Value* cast_row_ptr = builder.CreateBitCast(
      row_ptr, codegen->ptr_ptr_type(), "cast_row_ptr");
  llvm::Value* tuple_addr =
      builder.CreateInBoundsGEP(cast_row_ptr, tuple_offset, "tuple_addr");
  // Load the tuple*
  llvm::Value* tuple_ptr = builder.CreateLoad(tuple_addr, "tuple_ptr");

  // Check if tuple* is null only if the tuple is nullable
  if (tuple_is_nullable_) {
    llvm::Value* tuple_is_null = builder.CreateIsNull(tuple_ptr, "tuple_is_null");
    // Check slot is null only if the null indicator bit is set
    if (slot_is_nullable) {
      builder.CreateCondBr(tuple_is_null, ret_block, check_slot_null_indicator_block);
    } else {
      builder.CreateCondBr(tuple_is_null, ret_block, get_slot_block);
    }
  } else {
    if (slot_is_nullable) {
      builder.CreateBr(check_slot_null_indicator_block);
    } else {
      builder.CreateBr(get_slot_block);
    }
  }

  // Branch for tuple* != NULL.  Need to check if null-indicator is set
  if (slot_is_nullable) {
    builder.SetInsertPoint(check_slot_null_indicator_block);
    llvm::Value* is_slot_null = SlotDescriptor::CodegenIsNull(
        codegen, &builder, null_indicator_offset_, tuple_ptr);
    builder.CreateCondBr(is_slot_null, ret_block, get_slot_block);
  }

  // Branch for slot != NULL
  builder.SetInsertPoint(get_slot_block);
  llvm::Value* slot_ptr = builder.CreateInBoundsGEP(tuple_ptr, slot_offset, "slot_addr");
  llvm::Value* val_ptr = builder.CreateBitCast(slot_ptr,
      codegen->GetSlotPtrType(type_), "val_ptr");
  // Depending on the type, load the values we need
  llvm::Value* val = NULL;
  llvm::Value* ptr = NULL;
  llvm::Value* len = NULL;
  llvm::Value* time_of_day = NULL;
  llvm::Value* date = NULL;
  if (type_.IsVarLenStringType() || type_.IsCollectionType()) {
    llvm::Value* ptr_ptr = builder.CreateStructGEP(NULL, val_ptr, 0, "ptr_ptr");
    ptr = builder.CreateLoad(ptr_ptr, "ptr");
    llvm::Value* len_ptr = builder.CreateStructGEP(NULL, val_ptr, 1, "len_ptr");
    len = builder.CreateLoad(len_ptr, "len");
  } else if (type_.type == TYPE_CHAR || type_.type == TYPE_FIXED_UDA_INTERMEDIATE) {
    // ptr and len are the slot and its fixed length.
    ptr = builder.CreateBitCast(val_ptr, codegen->ptr_type());
    len = codegen->GetI32Constant(type_.len);
  } else if (type_.type == TYPE_TIMESTAMP) {
    llvm::Value* time_of_day_ptr =
        builder.CreateStructGEP(NULL, val_ptr, 0, "time_of_day_ptr");
    // Cast boost::posix_time::time_duration to i64
    llvm::Value* time_of_day_cast =
        builder.CreateBitCast(time_of_day_ptr, codegen->i64_ptr_type());
    time_of_day = builder.CreateLoad(time_of_day_cast, "time_of_day");
    llvm::Value* date_ptr = builder.CreateStructGEP(NULL, val_ptr, 1, "date_ptr");
    // Cast boost::gregorian::date to i32
    llvm::Value* date_cast =
        builder.CreateBitCast(date_ptr, codegen->i32_ptr_type());
    date = builder.CreateLoad(date_cast, "date");
  } else {
    // val_ptr is a native type
    val = builder.CreateLoad(val_ptr, "val");
  }
  builder.CreateBr(ret_block);

  // Return block
  builder.SetInsertPoint(ret_block);
  llvm::PHINode* is_null_phi =
      builder.CreatePHI(codegen->i8_type(), 2, "is_null_phi");
  if (tuple_is_nullable_) is_null_phi->addIncoming(one, entry_block);
  if (check_slot_null_indicator_block != NULL) {
    is_null_phi->addIncoming(one, check_slot_null_indicator_block);
  }
  is_null_phi->addIncoming(zero, get_slot_block);

  // Depending on the type, create phi nodes for each value needed to populate the return
  // *Val. The optimizer does a better job when there is a phi node for each value, rather
  // than having get_slot_block generate an AnyVal and having a single phi node over that.
  // TODO: revisit this code, can possibly be simplified
  if (type_.IsStringType() || type_.type == TYPE_FIXED_UDA_INTERMEDIATE
      || type_.IsCollectionType()) {
    DCHECK(ptr != NULL);
    DCHECK(len != NULL);
    llvm::PHINode* ptr_phi = builder.CreatePHI(ptr->getType(), 2, "ptr_phi");
    llvm::Value* null = llvm::Constant::getNullValue(ptr->getType());
    if (tuple_is_nullable_) {
      ptr_phi->addIncoming(null, entry_block);
    }
    if (check_slot_null_indicator_block != NULL) {
      ptr_phi->addIncoming(null, check_slot_null_indicator_block);
    }
    ptr_phi->addIncoming(ptr, get_slot_block);

    llvm::PHINode* len_phi = builder.CreatePHI(len->getType(), 2, "len_phi");
    null = llvm::ConstantInt::get(len->getType(), 0);
    if (tuple_is_nullable_) {
      len_phi->addIncoming(null, entry_block);
    }
    if (check_slot_null_indicator_block != NULL) {
      len_phi->addIncoming(null, check_slot_null_indicator_block);
    }
    len_phi->addIncoming(len, get_slot_block);

    CodegenAnyVal result =
        CodegenAnyVal::GetNonNullVal(codegen, &builder, type(), "result");
    result.SetIsNull(is_null_phi);
    result.SetPtr(ptr_phi);
    result.SetLen(len_phi);
    builder.CreateRet(result.GetLoweredValue());
  } else if (type_.type == TYPE_TIMESTAMP) {
    DCHECK(time_of_day != NULL);
    DCHECK(date != NULL);
    llvm::PHINode* time_of_day_phi =
        builder.CreatePHI(time_of_day->getType(), 2, "time_of_day_phi");
    llvm::Value* null = llvm::ConstantInt::get(time_of_day->getType(), 0);
    if (tuple_is_nullable_) {
      time_of_day_phi->addIncoming(null, entry_block);
    }
    if (check_slot_null_indicator_block != NULL) {
      time_of_day_phi->addIncoming(null, check_slot_null_indicator_block);
    }
    time_of_day_phi->addIncoming(time_of_day, get_slot_block);

    llvm::PHINode* date_phi = builder.CreatePHI(date->getType(), 2, "date_phi");
    null = llvm::ConstantInt::get(date->getType(), 0);
    if (tuple_is_nullable_) {
      date_phi->addIncoming(null, entry_block);
    }
    if (check_slot_null_indicator_block != NULL) {
      date_phi->addIncoming(null, check_slot_null_indicator_block);
    }
    date_phi->addIncoming(date, get_slot_block);

    CodegenAnyVal result =
        CodegenAnyVal::GetNonNullVal(codegen, &builder, type(), "result");
    result.SetIsNull(is_null_phi);
    result.SetTimeOfDay(time_of_day_phi);
    result.SetDate(date_phi);
    builder.CreateRet(result.GetLoweredValue());
  } else {
    DCHECK(val != NULL);
    llvm::PHINode* val_phi = builder.CreatePHI(val->getType(), 2, "val_phi");
    llvm::Value* null = llvm::Constant::getNullValue(val->getType());
    if (tuple_is_nullable_) {
      val_phi->addIncoming(null, entry_block);
    }
    if (check_slot_null_indicator_block != NULL) {
      val_phi->addIncoming(null, check_slot_null_indicator_block);
    }
    val_phi->addIncoming(val, get_slot_block);

    CodegenAnyVal result =
        CodegenAnyVal::GetNonNullVal(codegen, &builder, type(), "result");
    result.SetIsNull(is_null_phi);
    result.SetVal(val_phi);
    builder.CreateRet(result.GetLoweredValue());
  }

  *fn = codegen->FinalizeFunction(*fn);
  if (UNLIKELY(*fn == NULL)) return Status(TErrorCode::IR_VERIFY_FAILED, "SlotRef");
  codegen->RegisterExprFn(unique_slot_id, *fn);
  return Status::OK();
}

#define SLOT_REF_GET_FUNCTION(type_lit, type_val, type_c) \
    type_val SlotRef::Get##type_val##Interpreted( \
        ScalarExprEvaluator* eval, const TupleRow* row) const { \
      DCHECK_EQ(type_.type, type_lit); \
      Tuple* t = row->GetTuple(tuple_idx_); \
      if (t == NULL || t->IsNull(null_indicator_offset_)) return type_val::null(); \
      return type_val(*reinterpret_cast<type_c*>(t->GetSlot(slot_offset_))); \
    }

SLOT_REF_GET_FUNCTION(TYPE_BOOLEAN, BooleanVal, bool);
SLOT_REF_GET_FUNCTION(TYPE_TINYINT, TinyIntVal, int8_t);
SLOT_REF_GET_FUNCTION(TYPE_SMALLINT, SmallIntVal, int16_t);
SLOT_REF_GET_FUNCTION(TYPE_INT, IntVal, int32_t);
SLOT_REF_GET_FUNCTION(TYPE_BIGINT, BigIntVal, int64_t);
SLOT_REF_GET_FUNCTION(TYPE_FLOAT, FloatVal, float);
SLOT_REF_GET_FUNCTION(TYPE_DOUBLE, DoubleVal, double);

StringVal SlotRef::GetStringValInterpreted(
    ScalarExprEvaluator* eval, const TupleRow* row) const {
  DCHECK(type_.IsStringType() || type_.type == TYPE_FIXED_UDA_INTERMEDIATE);
  Tuple* t = row->GetTuple(tuple_idx_);
  if (t == NULL || t->IsNull(null_indicator_offset_)) return StringVal::null();
  StringVal result;
  if (type_.type == TYPE_CHAR || type_.type == TYPE_FIXED_UDA_INTERMEDIATE) {
    result.ptr = reinterpret_cast<uint8_t*>(t->GetSlot(slot_offset_));
    result.len = type_.len;
  } else {
    StringValue* sv = reinterpret_cast<StringValue*>(t->GetSlot(slot_offset_));
    sv->ToStringVal(&result);
  }
  return result;
}

TimestampVal SlotRef::GetTimestampValInterpreted(
    ScalarExprEvaluator* eval, const TupleRow* row) const {
  DCHECK_EQ(type_.type, TYPE_TIMESTAMP);
  Tuple* t = row->GetTuple(tuple_idx_);
  if (t == NULL || t->IsNull(null_indicator_offset_)) return TimestampVal::null();
  TimestampValue* tv = reinterpret_cast<TimestampValue*>(t->GetSlot(slot_offset_));
  TimestampVal result;
  tv->ToTimestampVal(&result);
  return result;
}

DecimalVal SlotRef::GetDecimalValInterpreted(
    ScalarExprEvaluator* eval, const TupleRow* row) const {
  DCHECK_EQ(type_.type, TYPE_DECIMAL);
  Tuple* t = row->GetTuple(tuple_idx_);
  if (t == NULL || t->IsNull(null_indicator_offset_)) return DecimalVal::null();
  switch (type_.GetByteSize()) {
    case 4:
      return DecimalVal(*reinterpret_cast<int32_t*>(t->GetSlot(slot_offset_)));
    case 8:
      return DecimalVal(*reinterpret_cast<int64_t*>(t->GetSlot(slot_offset_)));
    case 16:
      return DecimalVal(*reinterpret_cast<int128_t*>(t->GetSlot(slot_offset_)));
    default:
      DCHECK(false);
      return DecimalVal::null();
  }
}

DateVal SlotRef::GetDateValInterpreted(
    ScalarExprEvaluator* eval, const TupleRow* row) const {
  DCHECK_EQ(type_.type, TYPE_DATE);
  Tuple* t = row->GetTuple(tuple_idx_);
  if (t == nullptr || t->IsNull(null_indicator_offset_)) return DateVal::null();
  const DateValue dv(*reinterpret_cast<int32_t*>(t->GetSlot(slot_offset_)));
  return dv.ToDateVal();
}

CollectionVal SlotRef::GetCollectionValInterpreted(
    ScalarExprEvaluator* eval, const TupleRow* row) const {
  DCHECK(type_.IsCollectionType());
  Tuple* t = row->GetTuple(tuple_idx_);
  if (t == nullptr || t->IsNull(null_indicator_offset_)) return CollectionVal::null();
  CollectionValue* coll_value =
      reinterpret_cast<CollectionValue*>(t->GetSlot(slot_offset_));
  return CollectionVal(coll_value->ptr, coll_value->num_tuples);
}

} // namespace impala
