/* ----------------------------------------------------------------------- *//**
 *
 * @file FunctionHandle_impl.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_POSTGRES_FUNCTIONHANDLE_IMPL_HPP
#define MADLIB_POSTGRES_FUNCTIONHANDLE_IMPL_HPP

namespace madlib {

namespace dbconnector {

namespace postgres {

inline
FunctionHandle::Argument::Argument(AnyType inValue)
  : AnyType(inValue) { }

template <typename T>
inline
FunctionHandle::Argument::Argument(const T& inValue)
  : AnyType(inValue, true /* forceLazyConversionToDatum */) { }

inline
FunctionHandle::FunctionHandle(SystemInformation* inSysInfo, Oid inFuncID)
  : mSysInfo(inSysInfo),
    mFuncInfo(inSysInfo->functionInformation(inFuncID)),
    mFuncCallOptions(GarbageCollectionAfterCall) { }

inline
UDF::Pointer
FunctionHandle::funcPtr() {
    return mFuncInfo->cxx_func;
}

/**
 * @brief Return the OID of this function
 */
inline
Oid
FunctionHandle::funcID() const {
    return mFuncInfo->oid;
}

inline
FunctionHandle&
FunctionHandle::setFunctionCallOptions(uint32_t inFlags) {
    mFuncCallOptions = inFlags;
    return *this;
}

inline
FunctionHandle&
FunctionHandle::unsetFunctionCallOptions(uint32_t inFlags) {
    mFuncCallOptions &= ~inFlags;
    return *this;
}

inline
uint32_t
FunctionHandle::getFunctionCallOptions() const {
    return mFuncCallOptions;
}

/**
 * @brief Wrapper around FunctionCallInvoke
 *
 * We factor FunctionCallInvoke out in a separate function because local
 * variables could potentially be clobbered during the 'longjmp' otherwise.
 */
inline
Datum
FunctionHandle::internalInvoke(FunctionCallInfo inFCInfo) {
    Datum result = 0;
    MADLIB_PG_TRY {
        result = FunctionCallInvoke(inFCInfo);
    } MADLIB_PG_CATCH {
        throw std::runtime_error(std::string("Exception while invoking '")
            + mSysInfo->functionInformation(mFuncInfo->oid)->getFullName()
            + "'. Error was:\n" + MADLIB_PG_ERROR_DATA()->message);
    } MADLIB_PG_END_TRY;
    return result;
}

inline
AnyType
FunctionHandle::invoke(AnyType &args) {
    madlib_assert(args.isComposite(), std::logic_error(
        "FunctionHandle::invoke() called with simple type."));

    if (args.numFields() > mFuncInfo->nargs)
        throw std::invalid_argument(std::string("More arguments given than "
            "expected by '")
            + mSysInfo->functionInformation(mFuncInfo->oid)->getFullName()
            + "'.");

    bool hasNulls = false;
    for (uint16_t i = 0; i < args.numFields(); ++i)
        hasNulls |= args[i].isNull();

    // If function is strict, we must not call the function at all
    if (mFuncInfo->isstrict && hasNulls)
        return AnyType();

    if (mFuncInfo->cxx_func &&
        !(mFuncCallOptions & GarbageCollectionAfterCall)) {

        // We have called this function before, so we can now do a shortcut:
        // Directly call the C++ function without any detour through the backend
        AnyType::LazyConversionToDatumOverride raii(true);
        return mFuncInfo->cxx_func(args);
    }

    MemoryContext oldContext = NULL;
    MemoryContext callContext = NULL;
    if (mFuncCallOptions & GarbageCollectionAfterCall) {
        // In order to do garbage collection, we need to create a new
        // memory context
        callContext = AllocSetContextCreate(CurrentMemoryContext,
            "C++ AL / FunctionHandle::invoke memory context",
            ALLOCSET_DEFAULT_MINSIZE,
            ALLOCSET_DEFAULT_INITSIZE,
            ALLOCSET_DEFAULT_MAXSIZE);
        oldContext = MemoryContextSwitchTo(callContext);
    }

#if PG_VERSION_NUM >= 120000
    FunctionCallInfoBaseData funcPtrCallInfo;
    int nargs = args.numFields();
    MemSet(&funcPtrCallInfo, 0, SizeForFunctionCallInfo(nargs));
#else
    FunctionCallInfoData funcPtrCallInfo;
#endif
    // Initializes all the fields of a FunctionCallInfoData except for the arg[]
    // and argnull[] arrays
    madlib_InitFunctionCallInfoData(
        funcPtrCallInfo,

        // FmgrInfo *flinfo -- ptr to lookup info used for this call
        mFuncInfo->getFuncMgrInfo(),

        // short nargs -- # arguments actually passed
        args.numFields(),

        // Oid fncollation -- collation for function to use
        mSysInfo->collationOID,

        // fmNodePtr context -- pass info about context of call
        NULL,

        // fmNodePtr resultinfo -- pass or return extra info about result
        NULL
    );

#if PG_VERSION_NUM >= 120000
    for (uint16_t i = 0; i < funcPtrCallInfo.nargs; ++i) {

        funcPtrCallInfo.args[i].value = args[i].getAsDatum(&funcPtrCallInfo,
            mFuncInfo->getArgumentType(i));
        funcPtrCallInfo.args[i].isnull = args[i].isNull();
        elog(WARNING, "funcPtrCallInfo.args[i].value %lu funcPtrCallInfo.args[i].isnull %d", funcPtrCallInfo.args[i].value, funcPtrCallInfo.args[i].isnull);
    }
#else
    for (uint16_t i = 0; i < funcPtrCallInfo.nargs; ++i) {
        funcPtrCallInfo.arg[i]= args[i].getAsDatum(&funcPtrCallInfo,
            mFuncInfo->getArgumentType(i));
        funcPtrCallInfo.argnull[i] = args[i].isNull();
    }
#endif


    Datum result = internalInvoke(&funcPtrCallInfo);

    if (oldContext) {
        MemoryContextSwitchTo(oldContext);
        TypeInformation* typeInfo
            = mSysInfo->typeInformation(mFuncInfo->rettype);
        result = datumCopy(result, typeInfo->isByValue(), typeInfo->getLen());
        MemoryContextDelete(callContext);
    }

    return funcPtrCallInfo.isnull
        ? AnyType()
        : AnyType(mSysInfo, result, mFuncInfo->rettype, /* isMutable */ true);
}

inline
AnyType
FunctionHandle::operator()() {
    AnyType nil;
    return invoke(nil);
}

// In the following, we define
// AnyType operator()(FunctionHandle::Argument& inArgs1, ...,
//     FunctionHandle::Argument& inArgsN)
// using Boost.Preprocessor.
#define MADLIB_APPEND_ARG(z, n, data) \
    << data ## n
#define MADLIB_OPERATOR_DEF(z, n, _ignored) \
    inline \
    AnyType \
    FunctionHandle::operator()( \
        BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), \
            FunctionHandle::Argument inArg) \
    ) { \
        AnyType args; \
        args BOOST_PP_REPEAT(BOOST_PP_INC(n), MADLIB_APPEND_ARG, inArg); \
        return invoke(args); \
    }
BOOST_PP_REPEAT(MADLIB_FUNC_MAX_ARGS, MADLIB_OPERATOR_DEF, 0 /* ignored */)
#undef MADLIB_OPERATOR_DEF
#undef MADLIB_APPEND_ARG

inline
SystemInformation*
FunctionHandle::getSysInfo() const {
    return mSysInfo;
}

} // namespace postgres

} // namespace dbconnector

} // namespace madlib

#endif // defined(MADLIB_POSTGRES_FUNCTIONHANDLE_IMPL_HPP)
