/* ----------------------------------------------------------------------- *//**
 *
 * @file SystemInformation_impl.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_POSTGRES_SYSTEMINFORMATION_IMPL_HPP
#define MADLIB_POSTGRES_SYSTEMINFORMATION_IMPL_HPP

namespace madlib {

namespace dbconnector {

namespace postgres {

namespace {

/**
 * @brief Initialize an OID-to-data hash table
 */
inline
void
initializeOidHashTable(HTAB*& ioHashTable, MemoryContext inCacheContext,
    size_t inEntrySize, const char* inTabName, uint32_t inMaxNElems) {

    if (ioHashTable == NULL) {
        HASHCTL ctl;
        ctl.keysize = sizeof(Oid);
        ctl.entrysize = inEntrySize;
        ctl.hash = oid_hash;
        ctl.hcxt = inCacheContext;
        ioHashTable = madlib_hash_create(
            /* tabname -- a name for the table (for debugging purposes) */
            inTabName,
            /* nelem -- maximum number of elements expected */
            inMaxNElems,
            /* info: additional table parameters, as indicated by flags */
            &ctl,
            /* flags -- bitmask indicating which parameters to take from *info */
            HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT
        );
    }
}

/**
 * @brief Store cached system-catalog information in backend function handle
 *
 * @param inFmgrInfo Backend handle to the function
 * @param inSysInfo Our system-catalog information that should be stored
 *
 * A set-returning function uses \c fn_extra to store cross-call information.
 * See, e.g., init_MultiFuncCall() in funcapi.c. Fortunately, it stores a point
 * to a <tt>struct FuncCallContext</tt> in \c fn_extra, which in turn allows to
 * store user-defined data.
 */
inline
void
setSystemInformationInFmgrInfo(FmgrInfo* inFmgrInfo,
    SystemInformation* inSysInfo) {

    (inFmgrInfo->fn_retset
        ? static_cast<FuncCallContext*>(inFmgrInfo->fn_extra)->user_fctx
        : inFmgrInfo->fn_extra)
        = inSysInfo;
}

/**
 * @brief Get cached system-catalog information from backend function handle
 *
 * @see setSystemInformationInFmgrInfo()
 */
inline
SystemInformation*
getSystemInformationFromFmgrInfo(FmgrInfo* inFmgrInfo) {
    return static_cast<SystemInformation*>(inFmgrInfo->fn_retset
        ? static_cast<FuncCallContext*>(inFmgrInfo->fn_extra)->user_fctx
        : inFmgrInfo->fn_extra);
}

/**
 * @brief Get memory context from backend function handle
 *
 * The memory context returned may be used for storing user-defined data. In
 * SystemInformation::get(), we will use it for allocating a
 * <tt>struct SystemInformation</tt>.
 *
 * @see setSystemInformationInFmgrInfo()
 */
inline
MemoryContext
getMemoryContextFromFmgrInfo(FmgrInfo* inFmgrInfo) {
    return inFmgrInfo->fn_retset
        ? static_cast<FuncCallContext*>(inFmgrInfo->fn_extra)
            ->multi_call_memory_ctx
        : inFmgrInfo->fn_mcxt;
}

} // namespace

/**
 * @brief Get (and cache) information from the PostgreSQL catalog
 *
 * @param inFmgrInfo System-catalog information about the function. If no
 *     SystemInformation is currently available in struct FmgrInfo, this
 *     function will store it (and thus change the FmgrInfo struct).
 */
inline
SystemInformation*
SystemInformation::get(FunctionCallInfo fcinfo) {
    madlib_assert(fcinfo->flinfo,
        std::invalid_argument("Incomplete FunctionCallInfoData."));

    SystemInformation* sysInfo
        = getSystemInformationFromFmgrInfo(fcinfo->flinfo);

    if (!sysInfo) {
        MemoryContext memCtxt = getMemoryContextFromFmgrInfo(fcinfo->flinfo);

        sysInfo = static_cast<SystemInformation*>(
            madlib_MemoryContextAllocZero(
                memCtxt, sizeof(SystemInformation)));
        sysInfo->entryFuncOID = fcinfo->flinfo->fn_oid;
        sysInfo->cacheContext = memCtxt;
        sysInfo->collationOID = PG_GET_COLLATION();
        setSystemInformationInFmgrInfo(fcinfo->flinfo, sysInfo);
    }
    return sysInfo;
}

/**
 * @brief Get (and cache) information about a PostgreSQL type
 *
 * @param inPGInfo An PGInformation structure containing all cached information
 * @param inTypeID The OID of the type of interest
 */
inline
TypeInformation*
SystemInformation::typeInformation(Oid inTypeID) {
    TypeInformation* cachedTypeInfo = NULL;
    bool found = true;
    MemoryContext oldContext;
    HeapTuple tup;
    Form_pg_type pgType;

    // We arrange to look up info about types only once per series of
    // calls, assuming the type info doesn't change underneath us.
    initializeOidHashTable(types, cacheContext,
        sizeof(TypeInformation),
        "C++ AL / TypeInformation hash table",
        12);

    // BACKEND: Since we pass HASH_FIND, this function call will never perform
    // an allocation. There is nothing in the code path that would raise an
    // exception (including oid_hash()), so we are *not* wrapping in a PG_TRY()
    // block for performance reasons.
    cachedTypeInfo = static_cast<TypeInformation*>(
        hash_search(types, &inTypeID, HASH_FIND, &found));

    if (!found) {
        cachedTypeInfo = static_cast<TypeInformation*>(
            madlib_hash_search(types, &inTypeID, HASH_ENTER, &found));
        // cachedTypeInfo.oid is already set
        tup = madlib_SearchSysCache1(TYPEOID, ObjectIdGetDatum(inTypeID));
        // BACKEND: HeapTupleIsValid is just a macro
        if (!HeapTupleIsValid(tup)) {
            throw std::runtime_error("Error while looking up a type in the "
                "system catalog.");
        } else {
            // BACKEND: GETSTRUCT is just a macro
            pgType = reinterpret_cast<Form_pg_type>(GETSTRUCT(tup));
            std::strncpy(cachedTypeInfo->name, pgType->typname.data,
                NAMEDATALEN);
            cachedTypeInfo->len = pgType->typlen;
            cachedTypeInfo->byval = pgType->typbyval;
            cachedTypeInfo->type = pgType->typtype;

            if (cachedTypeInfo->type == TYPTYPE_COMPOSITE) {
                // BACKEND: MemoryContextSwitchTo just changes a global
                // variable
                oldContext = MemoryContextSwitchTo(cacheContext);
                // Since type ID != RECORDOID, typmod will not be used and
                // we can set it to -1
                // (RECORDOID is a pseudo type and used for transient record
                // types. They are identified by an index in array
                // RecordCacheArray defined in typcache.c.)
                cachedTypeInfo->tupdesc = madlib_lookup_rowtype_tupdesc_copy(
                    /* type_id */ inTypeID,
                    /* typmod */ -1);
                MemoryContextSwitchTo(oldContext);
            } else {
                cachedTypeInfo->tupdesc = NULL;
            }
            madlib_ReleaseSysCache(tup);
        }
    }

    return cachedTypeInfo;
}

/**
 * @brief Get (and cache) information about a PostgreSQL function
 *
 * @param inFuncID The OID of the function of interest
 * @return
 */
inline
FunctionInformation*
SystemInformation::functionInformation(Oid inFuncID) {
    FunctionInformation* cachedFuncInfo = NULL;
    bool found = true;
    HeapTuple tup;
    Form_pg_proc pgFunc;

    // We arrange to look up info about functions only once per series of
    // calls, assuming the function info doesn't change underneath us.
    initializeOidHashTable(functions, cacheContext,
        sizeof(FunctionInformation),
        "C++ AL / FunctionInformation hash table",
        8);

    // BACKEND: Since we pass HASH_FIND, this function call will never perform
    // an allocation. There is nothing in the code path that would raise an
    // exception (including oid_hash()), so we are *not* wrapping in a PG_TRY()
    // block for performance reasons.
    cachedFuncInfo = static_cast<FunctionInformation*>(
        hash_search(functions, &inFuncID, HASH_FIND, &found));

    if (!found) {
        cachedFuncInfo = static_cast<FunctionInformation*>(
            madlib_hash_search(functions, &inFuncID, HASH_ENTER, &found));
        // cachedFuncInfo.oid is already set
        cachedFuncInfo->mSysInfo = this;
        tup = madlib_SearchSysCache1(PROCOID, ObjectIdGetDatum(inFuncID));
        if (!HeapTupleIsValid(tup)) {
            throw std::runtime_error("Error while looking up a function in the "
                "system catalog.");
        } else {
            // BACKEND: GETSTRUCT is just a macro
            pgFunc = reinterpret_cast<Form_pg_proc>(GETSTRUCT(tup));
            cachedFuncInfo->cxx_func = NULL;
            cachedFuncInfo->flinfo.fn_oid = InvalidOid;
            // The number of arguments (excluding OUT params)
            cachedFuncInfo->nargs
                = static_cast<uint16_t>(pgFunc->proargtypes.dim1);
            cachedFuncInfo->polymorphic = false;
            cachedFuncInfo->isstrict = pgFunc->proisstrict;
            cachedFuncInfo->secdef = pgFunc->prosecdef;

            Oid* allargs;
            // We could use get_func_arg_info() but unfortunately that also
            // copied names and modes
            bool onlyINArguments = false;
            Datum allargtypes = madlib_SysCacheGetAttr(PROCOID, tup,
                Anum_pg_proc_proallargtypes, &onlyINArguments);

            if (onlyINArguments) {
                allargs = pgFunc->proargtypes.values;
            } else {
                // See get_func_arg_info(). We expect the arrays to be 1-D
                // arrays of the right types; verify that.
                // Ensure that array is not toasted. We do not worry about
                // a possible memory leak here. This code will be run only
                // once per entry function (into the C++ AL) and query, and
                // memory will already be garbage collected once the currenty
                // entry point is left.
                ArrayType* arr = madlib_DatumGetArrayTypeP(allargtypes);
                int numargs = ARR_DIMS(arr)[0];
                madlib_assert(ARR_NDIM(arr) == 1 && ARR_DIMS(arr)[0] >= 0 &&
                    !ARR_HASNULL(arr) && ARR_ELEMTYPE(arr) == OIDOID &&
                    numargs >= pgFunc->pronargs,
                    std::runtime_error("In SystemInformation::"
                        "functionInformation(): proallargtypes is not a vaid "
                        "one-dimensional Oid array"));
                allargs = reinterpret_cast<Oid*>(ARR_DATA_PTR(arr));
            }

            for (int i = 0; i < pgFunc->pronargs; ++i) {
                // Note that pgFunc->pronargs is the number of all arguments
                // (including OUT params)
                if (typeInformation(allargs[i])->getType()
                    == TYPTYPE_PSEUDO) {

                    cachedFuncInfo->polymorphic = true;
                    break;
                }
            }

            if (cachedFuncInfo->nargs == 0) {
                cachedFuncInfo->argtypes = NULL;
            } else {
                cachedFuncInfo->argtypes = static_cast<Oid*>(
                    madlib_MemoryContextAlloc(cacheContext,
                        cachedFuncInfo->nargs * sizeof(Oid)));
                std::memcpy(cachedFuncInfo->argtypes,
                    pgFunc->proargtypes.values,
                    cachedFuncInfo->nargs * sizeof(Oid));
            }

            cachedFuncInfo->rettype = pgFunc->prorettype;

            // If the return type is RECORDOID, we cannot yet determine the
            // tuple description, even if the function is not polymorphic.
            // For that, the expression parse tree is required.
            // If the return type is composite but not RECORDOID, the tuple
            // description will be stored with the type information, so no
            // need to have it here.
            cachedFuncInfo->tupdesc = NULL;
            madlib_ReleaseSysCache(tup);
        }
    }

    return cachedFuncInfo;
}

/**
 * @brief Retrieve tuple description for a composite type
 *
 * @param inTypeMod Transient record types have tye ID RECORDOID and are
 *     identified by an index in array RecordCacheArray (defined in typcache.c).
 *     This index is stored in the tdtypmod field of struct tupleDesc.
 *     See the description of \c tupleDesc in tupdesc.h.
 */
inline
TupleDesc
TypeInformation::getTupleDesc(int32_t inTypeMod) {
    if (tupdesc != NULL)
        // We have the tuple description in our cache, so return it
        return tupdesc;
    else if (oid == RECORDOID && inTypeMod >= 0) {
        // It is an anonymous type, but PostgreSQL has it in its own cache
        // In this case lookup_rowtype_tupdesc_noerror(RECORDOID, ...)
        // does currently not perform any actions that could rise an exception.
        // We might not want to rely on that, however (at the expense of
        // performance).
        TupleDesc pgCachedTupDesc = lookup_rowtype_tupdesc_noerror(oid,
            inTypeMod, /* noerror */ true);

        // The tupleDesc is in the cache (RecordCacheArray defined in
        // typcache.c) even before lookup_rowtype... is called. There is no
        // need to release the tupleDesc, though we do in order to avoid any
        // side effect.
        ReleaseTupleDesc(pgCachedTupDesc);
        return pgCachedTupDesc;
    }

    return NULL;
}

/**
 * @brief Determine whether a specified type is composite
 *
 * This is our cached replacement for type_is_rowtype() in lsyscache.c
 */
inline
bool
TypeInformation::isCompositeType() {
    return oid == RECORDOID || type == TYPTYPE_COMPOSITE;
}

/**
 * @brief Retrieve the name of the specified type
 */
inline
const char*
TypeInformation::getName() {
    return name;
}

inline
bool
TypeInformation::isByValue() {
    return byval;
}

inline
int16_t
TypeInformation::getLen() {
    return len;
}

inline
char
TypeInformation::getType() {
    return type;
}



/**
 * @brief Retrieve the type of a function argument
 *
 * @param inArgID The ID of the argument (first argument is 0)
 * @param inFmgrInfo System-catalog information about the function. For
 *     polymorphic functions, this should be non-NULL and contain the
 *     expression parse tree.
 * @return The OID of the type of the argument. The type ID of polymorphic
 *     arguments is resolved if possible, i.e., if the expression parse tree
 *     is available in <tt>inFmgrInfo->fn_expr</tt>.
 */
inline
Oid
FunctionInformation::getArgumentType(uint16_t inArgID, FmgrInfo* inFmgrInfo) {
    if (!inFmgrInfo)
        inFmgrInfo = getFuncMgrInfo();

    madlib_assert(inFmgrInfo && oid == inFmgrInfo->fn_oid, std::runtime_error(
        "Invalid arguments passed to FunctionInformation::getArgumentType()."));
    Oid typeID = argtypes[inArgID];
    TypeInformation* cachedTypeInfo = mSysInfo->typeInformation(typeID);

    if (cachedTypeInfo->getType() == TYPTYPE_PSEUDO
        && inFmgrInfo->fn_expr != NULL) {
        // Type is a pseudotype, so the actual type information is given
        // by the expression parse tree.
        // This would fail if no expression parse tree is present, i.e., if
        // inFmgrInfo->fn_expr == NULL.

        typeID = madlib_get_fn_expr_argtype(inFmgrInfo, inArgID);
    }

    return typeID;
}

/**
 * @brief Retrieve the function return type
 *
 * @param fcinfo Information about function call, including the function OID
 * @return The actual return type (i.e., with resolved pseudo-types)
 */
inline
Oid
FunctionInformation::getReturnType(FunctionCallInfo fcinfo) {
    madlib_assert(fcinfo->flinfo && oid == fcinfo->flinfo->fn_oid,
        std::runtime_error("Invalid arguments passed to "
            "FunctionInformation::getReturnType()."));

    Oid returnType = rettype;
    if (rettype != RECORDOID &&
        mSysInfo->typeInformation(rettype)->type == TYPTYPE_PSEUDO) {
        // The function is polymorphic, and the result type thus depends on the
        // expression parse tree. Note that the condition in the if-clause is
        // sufficient condition for cachedFuncInfo->polymorphic, but not a
        // necessary condition. (A function could have input arguments with
        // pseudo types, but a fixed return type.)

        madlib_assert(polymorphic,
            std::logic_error("Logical error: Function returns non-record "
                "pseudo type but is not polymorphic."));

        // This is not a composite type, so no need to pass anything for
        // resultTupleDesc
        madlib_get_call_result_type(fcinfo, &returnType,
            /* resultTupleDesc */ NULL);
    }

    return returnType;
}

/**
 * @brief Retrieve the tuple description of a function's return type
 *
 * @param fcinfo Information about function call, including the function OID
 * @return The tuple description if the return type is composite and NULL
 *     otherwise
 */
inline
TupleDesc
FunctionInformation::getReturnTupleDesc(FunctionCallInfo fcinfo) {
    madlib_assert(fcinfo->flinfo && oid == fcinfo->flinfo->fn_oid,
        std::runtime_error("Invalid arguments passed to "
            "FunctionInformation::getReturnTupleDesc()."));

    TupleDesc returnTupDesc = tupdesc;
    if (returnTupDesc == NULL) {
        if (rettype == RECORDOID) {
            MADLIB_PG_TRY {
                // The return type is known, so no need to pass anything for
                // resultTypeId
                // get_call_result_type() creates the tuple description using
                // lookup_rowtype_tupdesc_copy(), which is not reference-counted
                // So there is no need to release the TupleDesc
                get_call_result_type(fcinfo, /* resultTypeId */ NULL,
                    &returnTupDesc);
            } MADLIB_PG_DEFAULT_CATCH_AND_END_TRY;

            if (returnTupDesc == NULL) {
                throw std::runtime_error("MADLIB-870: C++ abstract layer has "
                        "not supported UDFs that return RECORD type without "
                        "tuple described at call time");
            }

            MADLIB_PG_TRY {
                if (!polymorphic) {
                    // Since the function is not polymorphic, we can store the
                    // tuple description for other calls
                    MemoryContext oldContext
                        = MemoryContextSwitchTo(mSysInfo->cacheContext);
                    tupdesc = CreateTupleDescCopyConstr(returnTupDesc);
                    MemoryContextSwitchTo(oldContext);
                }
            } MADLIB_PG_DEFAULT_CATCH_AND_END_TRY;
        } else {
            TypeInformation* cachedTypeInfo
                = mSysInfo->typeInformation(rettype);

            if (cachedTypeInfo->type == TYPTYPE_COMPOSITE)
                returnTupDesc = cachedTypeInfo->tupdesc;
        }
    }

    return returnTupDesc;
}

/**
 * @brief Retrieve (cross-call) system-catalog information about the function
 *
 * @param inFuncID The OID of the function of interest
 * @return A filled FmgrInfo struct which uses the current SystemInformation
 *     object as system-catalog cache
 *
 * If no FmgrInfo data is stored for the function of interest, this
 * function creates a new struct FmgrInfo and stores it in the current
 * FunctionInformation object. It also links the new FmgrInfo struct to the
 * currently used SystemInformation object.
 *
 * @note Cached FmgrInfo data is *not* used for entry functions (i.e., the
 *     immediate call by the backend). For the entry function, a complete
 *     struct FunctionCallInfoData is passed by the backend itself, which is
 *     used instead (as it also contains the parse tree).
 */
inline
FmgrInfo*
FunctionInformation::getFuncMgrInfo() {
    // Initially flinfo.fn_oid is set to InvalidOid
    if (flinfo.fn_oid != oid) {
        // Check permissions
        if (madlib_pg_proc_aclcheck(oid, GetUserId(), ACL_EXECUTE)
            != ACLCHECK_OK) {

            throw std::invalid_argument(std::string("No privilege to run "
                "function '") + getFullName() + "'.");
        }

        // cacheContext will be set as fn_mcxt.
        madlib_fmgr_info_cxt(oid, &flinfo, mSysInfo->cacheContext);

        if (!secdef) {
            // If the function is SECURITY DEFINER then fmgr_info_cxt() has
            // set up flinfo so that what we will actually
            // call fmgr_security_definer() in fmgr.c, which then calls the
            // "real" function. Because of this additional layer, and since
            // fmgr_security_definer() uses the fn_extra field of
            // struct FmgrInfo in an opaque way (it points to a struct that is
            // local to fmgr.c), we only initialize the cache if the function
            // is *not* SECURITY DEFINER.
            setSystemInformationInFmgrInfo(&flinfo, mSysInfo);
        }
    }

    return &flinfo;
}

/**
 * @brief Retrieve the full function name (including arguments)
 *
 * We currently do not cache this information because we expect this function
 * to be primarily called by error handlers.
 */
inline
const char*
FunctionInformation::getFullName() {
    return madlib_format_procedure(oid);
}

} // namespace postgres

} // namespace dbconnector

} // namespace madlib

#endif // defined(MADLIB_POSTGRES_SYSTEMINFORMATION_IMPL_HPP)
