/*
 * Copyright 2013, The Android Open Source Project
 *
 * 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.
 */

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>

#include <cstdarg>
#include <cctype>

#include <algorithm>
#include <sstream>
#include <string>
#include <utility>

#include "os_sep.h"
#include "slang_rs_context.h"
#include "slang_rs_export_var.h"
#include "slang_rs_export_foreach.h"
#include "slang_rs_export_func.h"
#include "slang_rs_reflect_utils.h"
#include "slang_version.h"
#include "slang_utils.h"

#include "slang_rs_reflection_cpp.h"

using namespace std;

namespace slang {

#define RS_TYPE_ITEM_CLASS_NAME          "Item"

#define RS_ELEM_PREFIX "__rs_elem_"

static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
  static const char *MatrixTypeCNameMap[] = {
    "rs_matrix2x2",
    "rs_matrix3x3",
    "rs_matrix4x4",
  };
  unsigned Dim = EMT->getDim();

  if ((Dim - 2) < (sizeof(MatrixTypeCNameMap) / sizeof(const char*)))
    return MatrixTypeCNameMap[ EMT->getDim() - 2 ];

  slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
  return NULL;
}


static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      return RSExportPrimitiveType::getRSReflectionType(
          static_cast<const RSExportPrimitiveType*>(ET))->c_name;
    }
    case RSExportType::ExportClassPointer: {
      const RSExportType *PointeeType =
          static_cast<const RSExportPointerType*>(ET)->getPointeeType();

      if (PointeeType->getClass() != RSExportType::ExportClassRecord)
        return "android::RSC::sp<android::RSC::Allocation>";
      else
        return PointeeType->getElementName();
    }
    case RSExportType::ExportClassVector: {
      const RSExportVectorType *EVT =
          static_cast<const RSExportVectorType*>(ET);
      std::stringstream VecName;
      VecName << EVT->getRSReflectionType(EVT)->rs_c_vector_prefix
              << EVT->getNumElement();
      return VecName.str();
    }
    case RSExportType::ExportClassMatrix: {
      return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
    }
    case RSExportType::ExportClassConstantArray: {
      // TODO: Fix this for C arrays!
      const RSExportConstantArrayType* CAT =
          static_cast<const RSExportConstantArrayType*>(ET);
      std::string ElementTypeName = GetTypeName(CAT->getElementType());
      if (Brackets) {
        ElementTypeName.append("[]");
      }
      return ElementTypeName;
    }
    case RSExportType::ExportClassRecord: {
      // TODO: Fix for C structs!
      return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }

  return "";
}


RSReflectionCpp::RSReflectionCpp(const RSContext *con)
    : RSReflectionBase(con) {
  clear();
}

RSReflectionCpp::~RSReflectionCpp() {
}

bool RSReflectionCpp::reflect(const string &OutputPathBase,
                              const string &InputFileName,
                              const string &OutputBCFileName) {
  mInputFileName = InputFileName;
  mOutputPath = OutputPathBase + OS_PATH_SEPARATOR_STR;
  mOutputBCFileName = OutputBCFileName;
  mClassName = string("ScriptC_") + stripRS(InputFileName);

  std::string Path =
      RSSlangReflectUtils::ComputePackagedPath(OutputPathBase.c_str(), "");

  std::string ErrorMsg;
  if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg)) {
    fprintf(stderr, "Error: Could not create path %s - %s\n",
            Path.c_str(), ErrorMsg.c_str());
    return false;
  }

  makeHeader("android::RSC::ScriptC");
  std::vector< std::string > header(mText);
  mText.clear();

  makeImpl("android::RSC::ScriptC");
  std::vector< std::string > cpp(mText);
  mText.clear();


  writeFile(mClassName + ".h", header);
  writeFile(mClassName + ".cpp", cpp);


  return true;
}


#define RS_TYPE_CLASS_NAME_PREFIX        "ScriptField_"



bool RSReflectionCpp::makeHeader(const std::string &baseClass) {
  startFile(mClassName + ".h");

  write("");
  write("#include \"RenderScript.h\"");
  write("using namespace android::RSC;");
  write("");

  // Imports
  //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
      //out() << "import " << Import[i] << ";" << std::endl;
  //out() << std::endl;

  if (!baseClass.empty()) {
    write("class " + mClassName + " : public " + baseClass + " {");
  } else {
    write("class " + mClassName + " {");
  }

  write("private:");
  uint32_t slot = 0;
  incIndent();
  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
         E = mRSContext->export_vars_end(); I != E; I++, slot++) {
    const RSExportVar *ev = *I;
    if (!ev->isConst()) {
      write(GetTypeName(ev->getType()) + " " RS_EXPORT_VAR_PREFIX
            + ev->getName() + ";");
    }
  }

  for (RSContext::const_export_foreach_iterator
           I = mRSContext->export_foreach_begin(),
           E = mRSContext->export_foreach_end(); I != E; I++) {
    const RSExportForEach *EF = *I;
    const RSExportType *IET = EF->getInType();
    const RSExportType *OET = EF->getOutType();
    if (IET) {
      genTypeInstanceFromPointer(IET);
    }
    if (OET) {
      genTypeInstanceFromPointer(OET);
    }
  }

  for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
                                       E = mTypesToCheck.end();
       I != E;
       I++) {
    write("android::RSC::sp<const android::RSC::Element> " RS_ELEM_PREFIX
          + *I + ";");
  }

  decIndent();

  write("public:");
  incIndent();
  write(mClassName + "(android::RSC::sp<android::RSC::RS> rs);");
  write("virtual ~" + mClassName + "();");
  write("");


  // Reflect export variable
  slot = 0;
  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
         E = mRSContext->export_vars_end(); I != E; I++, slot++) {
    genExportVariable(*I);
  }

  // Reflect export for each functions
  for (RSContext::const_export_foreach_iterator
           I = mRSContext->export_foreach_begin(),
           E = mRSContext->export_foreach_end(); I != E; I++) {
    const RSExportForEach *ef = *I;
    if (ef->isDummyRoot()) {
      write("// No forEach_root(...)");
      continue;
    }

    ArgTy Args;
    stringstream ss;
    ss << "void forEach_" << ef->getName() << "(";

    if (ef->hasIn()) {
      Args.push_back(std::make_pair(
          "android::RSC::sp<const android::RSC::Allocation>", "ain"));
    }

    if (ef->hasOut() || ef->hasReturn()) {
      Args.push_back(std::make_pair(
          "android::RSC::sp<const android::RSC::Allocation>", "aout"));
    }

    const RSExportRecordType *ERT = ef->getParamPacketType();
    if (ERT) {
      for (RSExportForEach::const_param_iterator i = ef->params_begin(),
           e = ef->params_end(); i != e; i++) {
        RSReflectionTypeData rtd;
        (*i)->getType()->convertToRTD(&rtd);
        Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
      }
    }
    makeArgs(ss, Args);
    ss << ");";
    write(ss);
  }


  // Reflect export function
  for (RSContext::const_export_func_iterator
        I = mRSContext->export_funcs_begin(),
        E = mRSContext->export_funcs_end(); I != E; I++) {
    const RSExportFunc *ef = *I;

    stringstream ss;
    makeFunctionSignature(ss, false, ef);
    write(ss);
  }

  decIndent();
  write("};");
  return true;
}

bool RSReflectionCpp::writeBC() {
  FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb");
  if (pfin == NULL) {
    fprintf(stderr, "Error: could not read file %s\n",
            mOutputBCFileName.c_str());
    return false;
  }

  unsigned char buf[16];
  int read_length;
  write("static const unsigned char __txt[] = {");
  incIndent();
  while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
    string s;
    for (int i = 0; i < read_length; i++) {
      char buf2[16];
      snprintf(buf2, sizeof(buf2), "0x%02x,", buf[i]);
      s += buf2;
    }
    write(s);
  }
  decIndent();
  write("};");
  write("");
  return true;
}

bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
  startFile(mClassName + ".cpp");

  write("");
  write("#include \"" + mClassName + ".h\"");
  write("");

  writeBC();

  // Imports
  //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
      //out() << "import " << Import[i] << ";" << std::endl;
  //out() << std::endl;

  write("\n");
  stringstream ss;
  const std::string &packageName = mRSContext->getReflectJavaPackageName();
  ss << mClassName << "::" << mClassName
     << "(android::RSC::sp<android::RSC::RS> rs):\n"
        "        ScriptC(rs, __txt, sizeof(__txt), \""
     << stripRS(mInputFileName) << "\", " << stripRS(mInputFileName).length()
     << ", \"/data/data/" << packageName << "/app\", sizeof(\"" << packageName << "\")) {";
  write(ss);
  ss.str("");
  incIndent();
  for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
                                       E = mTypesToCheck.end();
       I != E;
       I++) {
    write(RS_ELEM_PREFIX + *I + " = android::RSC::Element::" + *I + "(mRS);");
  }

  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
                                            E = mRSContext->export_vars_end();
       I != E;
       I++) {
    const RSExportVar *EV = *I;
    if (!EV->getInit().isUninit()) {
      genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
    } else {
      genZeroInitExportVariable(EV->getName());
    }
  }
  decIndent();
  write("}");
  write("");

  write(mClassName + "::~" + mClassName + "() {");
  write("}");
  write("");

  // Reflect export for each functions
  uint32_t slot = 0;
  for (RSContext::const_export_foreach_iterator
       I = mRSContext->export_foreach_begin(),
       E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
    const RSExportForEach *ef = *I;
    if (ef->isDummyRoot()) {
      write("// No forEach_root(...)");
      continue;
    }

    stringstream tmp;
    ArgTy Args;
    tmp << "void " << mClassName << "::forEach_" << ef->getName() << "(";

    if (ef->hasIn()) {
      Args.push_back(std::make_pair(
          "android::RSC::sp<const android::RSC::Allocation>", "ain"));
    }

    if (ef->hasOut() || ef->hasReturn()) {
      Args.push_back(std::make_pair(
          "android::RSC::sp<const android::RSC::Allocation>", "aout"));
    }

    const RSExportRecordType *ERT = ef->getParamPacketType();
    if (ERT) {
      for (RSExportForEach::const_param_iterator i = ef->params_begin(),
           e = ef->params_end(); i != e; i++) {
        RSReflectionTypeData rtd;
        (*i)->getType()->convertToRTD(&rtd);
        Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
      }
    }
    makeArgs(tmp, Args);

    tmp << ") {";
    write(tmp);
    tmp.str("");

    const RSExportType *IET = ef->getInType();
    const RSExportType *OET = ef->getOutType();

    incIndent();
    if (IET) {
      genTypeCheck(IET, "ain");
    }

    if (OET) {
      genTypeCheck(OET, "aout");
    }
    decIndent();

    std::string FieldPackerName = ef->getName() + "_fp";
    if (ERT) {
      if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
        genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
      }
    }
    tmp << "    forEach(" << slot << ", ";

    if (ef->hasIn()) {
      tmp << "ain, ";
    } else {
      tmp << "NULL, ";
    }

    if (ef->hasOut() || ef->hasReturn()) {
      tmp << "aout, ";
    } else {
      tmp << "NULL, ";
    }

    // FIXME (no support for usrData with C++ kernels)
    tmp << "NULL, 0);";
    write(tmp);

    write("}");
    write("");
  }

  slot = 0;
  // Reflect export function
  for (RSContext::const_export_func_iterator
       I = mRSContext->export_funcs_begin(),
       E = mRSContext->export_funcs_end(); I != E; I++) {
    const RSExportFunc *ef = *I;

    stringstream ss;
    makeFunctionSignature(ss, true, ef);
    write(ss);
    ss.str("");
    const RSExportRecordType *params = ef->getParamPacketType();
    size_t param_len = 0;
    if (params) {
      param_len = RSExportType::GetTypeAllocSize(params);
      if (genCreateFieldPacker(params, "__fp")) {
        genPackVarOfType(params, NULL, "__fp");
      }
    }

    ss.str("");
    ss << "    invoke(" << slot;
    if (params) {
      ss << ", __fp.getData(), " << param_len << ");";
    } else {
      ss << ", NULL, 0);";
    }
    write(ss);

    write("}");
    write("");

    slot++;
  }

  decIndent();
  return true;
}

void RSReflectionCpp::genExportVariable(const RSExportVar *EV) {
  const RSExportType *ET = EV->getType();

  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      genPrimitiveTypeExportVariable(EV);
      break;
    }
    case RSExportType::ExportClassPointer: {
      genPointerTypeExportVariable(EV);
      break;
    }
    case RSExportType::ExportClassVector: {
      genVectorTypeExportVariable(EV);
      break;
    }
    case RSExportType::ExportClassMatrix: {
      genMatrixTypeExportVariable(EV);
      break;
    }
    case RSExportType::ExportClassConstantArray: {
      genConstantArrayTypeExportVariable(EV);
      break;
    }
    case RSExportType::ExportClassRecord: {
      genRecordTypeExportVariable(EV);
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }
}


void RSReflectionCpp::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
  RSReflectionTypeData rtd;
  EV->getType()->convertToRTD(&rtd);

  if (!EV->isConst()) {
    write(string("void set_") + EV->getName() + "(" + rtd.type->c_name +
          " v) {");
    stringstream tmp;
    tmp << getNextExportVarSlot();
    write(string("    setVar(") + tmp.str() + ", &v, sizeof(v));");
    write(string("    " RS_EXPORT_VAR_PREFIX) + EV->getName() + " = v;");
    write("}");
  }
  write(string(rtd.type->c_name) + " get_" + EV->getName() + "() const {");
  if (EV->isConst()) {
    const clang::APValue &val = EV->getInit();
    bool isBool = !strcmp(rtd.type->c_name, "bool");
    write(string("    return ") + genInitValue(val, isBool) + ";");
  } else {
    write(string("    return " RS_EXPORT_VAR_PREFIX) + EV->getName() + ";");
  }
  write("}");
  write("");
}

void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
  const RSExportType *ET = EV->getType();

  slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
              "Variable should be type of pointer here");

  std::string TypeName = GetTypeName(ET);
  std::string VarName = EV->getName();

  RSReflectionTypeData rtd;
  EV->getType()->convertToRTD(&rtd);
  uint32_t slot = getNextExportVarSlot();

  if (!EV->isConst()) {
    write(string("void bind_") + VarName + "(" + TypeName +
          " v) {");
    stringstream tmp;
    tmp << slot;
    write(string("    bindAllocation(v, ") + tmp.str() + ");");
    write(string("    " RS_EXPORT_VAR_PREFIX) + VarName + " = v;");
    write("}");
  }
  write(TypeName + " get_" + VarName + "() const {");
  if (EV->isConst()) {
    const clang::APValue &val = EV->getInit();
    bool isBool = !strcmp(TypeName.c_str(), "bool");
    write(string("    return ") + genInitValue(val, isBool) + ";");
  } else {
    write(string("    return " RS_EXPORT_VAR_PREFIX) + VarName + ";");
  }
  write("}");
  write("");

}

void RSReflectionCpp::genVectorTypeExportVariable(const RSExportVar *EV) {
  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
              "Variable should be type of vector here");

  const RSExportVectorType *EVT =
      static_cast<const RSExportVectorType*>(EV->getType());
  slangAssert(EVT != NULL);

  RSReflectionTypeData rtd;
  EVT->convertToRTD(&rtd);

  std::stringstream ss;

  if (!EV->isConst()) {
    ss << "void set_" << EV->getName() << "(" << rtd.type->rs_c_vector_prefix
       << EVT->getNumElement() << " v) {";
    write(ss);
    ss.str("");
    ss << getNextExportVarSlot();
    write(string("    setVar(") + ss.str() + ", &v, sizeof(v));");
    ss.str("");
    write(string("    " RS_EXPORT_VAR_PREFIX) + EV->getName() + " = v;");
    write("}");
  }
  ss << rtd.type->rs_c_vector_prefix << EVT->getNumElement() << " get_"
     << EV->getName() << "() const {";
  write(ss);
  ss.str("");
  if (EV->isConst()) {
    const clang::APValue &val = EV->getInit();
    write(string("    return ") + genInitValue(val, false) + ";");
  } else {
    write(string("    return " RS_EXPORT_VAR_PREFIX) + EV->getName() + ";");
  }
  write("}");
  write("");
}

void RSReflectionCpp::genMatrixTypeExportVariable(const RSExportVar *EV) {
  slangAssert(false);
}

void RSReflectionCpp::genConstantArrayTypeExportVariable(
    const RSExportVar *EV) {
  slangAssert(false);
}

void RSReflectionCpp::genRecordTypeExportVariable(const RSExportVar *EV) {
  slangAssert(false);
}


void RSReflectionCpp::makeFunctionSignature(
    std::stringstream &ss,
    bool isDefinition,
    const RSExportFunc *ef) {
  ss << "void ";
  if (isDefinition) {
    ss << mClassName << "::";
  }
  ss << "invoke_" << ef->getName() << "(";

  if (ef->getParamPacketType()) {
    bool FirstArg = true;
    for (RSExportFunc::const_param_iterator i = ef->params_begin(),
         e = ef->params_end(); i != e; i++) {
      RSReflectionTypeData rtd;
      (*i)->getType()->convertToRTD(&rtd);
      if (!FirstArg) {
        ss << ", ";
      } else {
        FirstArg = false;
      }
      ss << rtd.type->c_name << " " << (*i)->getName();
    }
  }

  if (isDefinition) {
    ss << ") {";
  } else {
    ss << ");";
  }
}

void RSReflectionCpp::makeArgs(std::stringstream &ss, const ArgTy& Args) {
  bool FirstArg = true;

  for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
    if (!FirstArg) {
      ss << ", ";
    } else {
      FirstArg = false;
    }

    ss << I->first << " " << I->second;
  }
}

bool RSReflectionCpp::genCreateFieldPacker(const RSExportType *ET,
                                           const char *FieldPackerName) {
  size_t AllocSize = RSExportType::GetTypeAllocSize(ET);

  if (AllocSize > 0) {
    std::stringstream ss;
    ss << "    FieldPacker " << FieldPackerName << "("
       << AllocSize << ");";
    write(ss);
    return true;
  }

  return false;
}

void RSReflectionCpp::genPackVarOfType(const RSExportType *ET,
                                       const char *VarName,
                                       const char *FieldPackerName) {
  std::stringstream ss;
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassPointer:
    case RSExportType::ExportClassMatrix: {
      ss << "    " << FieldPackerName << ".add(" << VarName << ");";
      write(ss);
      break;
    }
    case RSExportType::ExportClassConstantArray: {
      /*const RSExportConstantArrayType *ECAT =
          static_cast<const RSExportConstantArrayType *>(ET);

      // TODO(zonr): more elegant way. Currently, we obtain the unique index
      //             variable (this method involves recursive call which means
      //             we may have more than one level loop, therefore we can't
      //             always use the same index variable name here) name given
      //             in the for-loop from counting the '.' in @VarName.
      unsigned Level = 0;
      size_t LastDotPos = 0;
      std::string ElementVarName(VarName);

      while (LastDotPos != std::string::npos) {
        LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
        Level++;
      }
      std::string IndexVarName("ct");
      IndexVarName.append(llvm::utostr_32(Level));

      C.indent() << "for (int " << IndexVarName << " = 0; " <<
                          IndexVarName << " < " << ECAT->getSize() << "; " <<
                          IndexVarName << "++)";
      C.startBlock();

      ElementVarName.append("[" + IndexVarName + "]");
      genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
                       FieldPackerName);

      C.endBlock();*/
      break;
    }
    case RSExportType::ExportClassRecord: {
      const RSExportRecordType *ERT =
          static_cast<const RSExportRecordType*>(ET);
      // Relative pos from now on in field packer
      unsigned Pos = 0;

      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
               E = ERT->fields_end();
           I != E;
           I++) {
        const RSExportRecordType::Field *F = *I;
        std::string FieldName;
        size_t FieldOffset = F->getOffsetInParent();
        size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
        size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());

        if (VarName != NULL)
          FieldName = VarName + ("." + F->getName());
        else
          FieldName = F->getName();

        if (FieldOffset > Pos) {
          ss.str("");
          ss << "    " << FieldPackerName << ".skip("
             << (FieldOffset - Pos) << ");";
          write(ss);
        }

        genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);

        // There is padding in the field type
        if (FieldAllocSize > FieldStoreSize) {
          ss.str("");
          ss << "    " << FieldPackerName << ".skip("
             << (FieldAllocSize - FieldStoreSize) << ");";
          write(ss);
        }

        Pos = FieldOffset + FieldAllocSize;
      }

      // There maybe some padding after the struct
      if (RSExportType::GetTypeAllocSize(ERT) > Pos) {
        ss.str("");
        ss << "    " << FieldPackerName << ".skip("
           << RSExportType::GetTypeAllocSize(ERT) - Pos << ");";
        write(ss);
      }
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }
}


void RSReflectionCpp::genTypeCheck(const RSExportType *ET,
                                   const char *VarName) {
  stringstream tmp;
  tmp << "// Type check for " << VarName;
  write(tmp);
  tmp.str("");

  if (ET->getClass() == RSExportType::ExportClassPointer) {
    const RSExportPointerType *EPT =
        static_cast<const RSExportPointerType*>(ET);
    ET = EPT->getPointeeType();
  }

  std::string TypeName;
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassRecord: {
      TypeName = ET->getElementName();
      break;
    }

    default:
      break;
  }

  if (!TypeName.empty()) {
    //tmp << "// TypeName: " << TypeName;
    tmp << "if (!" << VarName
        << "->getType()->getElement()->isCompatible("
        << RS_ELEM_PREFIX
        << TypeName << ")) {";
    write(tmp);

    incIndent();
    write("mRS->throwError(RS_ERROR_RUNTIME_ERROR, "
          "\"Incompatible type\");");
    write("return;");
    decIndent();

    write("}");
  }
}

void RSReflectionCpp::genTypeInstanceFromPointer(const RSExportType *ET) {
  if (ET->getClass() == RSExportType::ExportClassPointer) {
    // For pointer parameters to original forEach kernels.
    const RSExportPointerType *EPT =
        static_cast<const RSExportPointerType*>(ET);
    genTypeInstance(EPT->getPointeeType());
  } else {
    // For handling pass-by-value kernel parameters.
    genTypeInstance(ET);
  }
}

void RSReflectionCpp::genTypeInstance(const RSExportType *ET) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassConstantArray:
    case RSExportType::ExportClassRecord: {
      std::string TypeName = ET->getElementName();
      addTypeNameForElement(TypeName);
      break;
    }

    default:
      break;
  }
}

void RSReflectionCpp::genInitExportVariable(const RSExportType *ET,
                                            const std::string &VarName,
                                            const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");

  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      const RSExportPrimitiveType *EPT =
          static_cast<const RSExportPrimitiveType*>(ET);
      if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
        genInitBoolExportVariable(VarName, Val);
      } else {
        genInitPrimitiveExportVariable(VarName, Val);
      }
      break;
    }
    case RSExportType::ExportClassPointer: {
      if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
        std::cerr << "Initializer which is non-NULL to pointer type variable "
                     "will be ignored" << std::endl;
      break;
    }
    case RSExportType::ExportClassVector: {
      const RSExportVectorType *EVT =
          static_cast<const RSExportVectorType*>(ET);
      switch (Val.getKind()) {
        case clang::APValue::Int:
        case clang::APValue::Float: {
          for (unsigned i = 0; i < EVT->getNumElement(); i++) {
            std::string Name = VarName + "." + getVectorAccessor(i);
            genInitPrimitiveExportVariable(Name, Val);
          }
          break;
        }
        case clang::APValue::Vector: {
          unsigned NumElements =
              std::min(static_cast<unsigned>(EVT->getNumElement()),
                       Val.getVectorLength());
          for (unsigned i = 0; i < NumElements; i++) {
            const clang::APValue &ElementVal = Val.getVectorElt(i);
            std::string Name = VarName + "." + getVectorAccessor(i);
            genInitPrimitiveExportVariable(Name, ElementVal);
          }
          break;
        }
        case clang::APValue::MemberPointer:
        case clang::APValue::Uninitialized:
        case clang::APValue::ComplexInt:
        case clang::APValue::ComplexFloat:
        case clang::APValue::LValue:
        case clang::APValue::Array:
        case clang::APValue::Struct:
        case clang::APValue::Union:
        case clang::APValue::AddrLabelDiff: {
          slangAssert(false && "Unexpected type of value of initializer.");
        }
      }
      break;
    }
    case RSExportType::ExportClassMatrix:
    case RSExportType::ExportClassConstantArray:
    case RSExportType::ExportClassRecord: {
      slangAssert(false && "Unsupported initializer for record/matrix/constant "
                           "array type variable currently");
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }
  return;
}

void RSReflectionCpp::genZeroInitExportVariable(const std::string &VarName) {
  std::stringstream ss;
  ss << "memset(&" RS_EXPORT_VAR_PREFIX << VarName << ", 0, sizeof("
     << RS_EXPORT_VAR_PREFIX << VarName << "));";
  write(ss);
}

void RSReflectionCpp::genInitPrimitiveExportVariable(
    const std::string &VarName,
    const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");

  std::stringstream ss;
  ss << RS_EXPORT_VAR_PREFIX << VarName << " = "
     << RSReflectionBase::genInitValue(Val) << ";";
  write(ss);
}

void RSReflectionCpp::genInitBoolExportVariable(const std::string &VarName,
                                                const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");
  slangAssert((Val.getKind() == clang::APValue::Int) &&
              "Bool type has wrong initial APValue");

  std::stringstream ss;
  ss << RS_EXPORT_VAR_PREFIX << VarName << " = "
     << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";";
  write(ss);
}

}  // namespace slang
