/* ----------------------------------------------------------------------- *//**
 *
 * @file AbstractDBInterface.hpp
 *
 *//* ----------------------------------------------------------------------- */

/**
 * @brief Abstract base class for the interface to a DBMS backend
 *
 * This class provides the interface that MADlib modules use for communicating
 * wit the DBMS backend. Every MADlib module function is passed a reference to
 * an AbstractDBInterface object as first argument.
 */
class AbstractDBInterface {
protected:
    /**
     * @brief Differentiate between Armadillo warnings and errors.
     *
     * Armadillo only uses one output stream. This requires us to provide some
     * additional checks for disptaching messages correctly.
     */
    class ArmadilloOutputStreamBuffer : public AbstractOutputStreamBuffer<> {
    public:
        ArmadilloOutputStreamBuffer(
            AbstractOutputStreamBuffer<> &inRelayStream)
        :   mRelayStream(inRelayStream), mError(false) { }

        /**
         * @brief If message is info/warning, relay output. Otherwise, hold it
         *        back.
         * 
         * arma::arma_stop throws a std::runtime_error with any empty what
         * string. The connector library is expected to test on runtime_errors
         * whether we have an error message available.
         */
        void output(char *inMsg, uint32_t inLength) {
            bool isRunTimeError = false;
            const char *kRunTimeErrStr = "run-time error: ";
            char *strStart = inMsg;
            char *strEnd;
            
            for (strStart = inMsg;
                std::isspace(*strStart, std::locale::classic());
                strStart++) ;
            if (std::strncmp(strStart, kRunTimeErrStr,
                    std::strlen(kRunTimeErrStr)) == 0) {
                
                isRunTimeError = true;
                for (strEnd = &inMsg[inLength - 1];
                    std::isspace(*strEnd, std::locale::classic());
                    strEnd--) ;
                *(++strEnd) = '\0';
                
                mTrimmedMsg = strStart;
                mError = true;
                return;
            } else if (*strStart == '\0') {
                // Ignore if the stream gets flushed with nothing in the buffer
                return;
            }
            
            mRelayStream.output(inMsg, inLength);
        }
        
        /**
         * @brief Return a C string containing the last error message, NULL if
         *        no error has occurred.
         *
         * @internal There is no need to reset the error message because an
         *           error will eventually become an exception.
         */
        const char *error() {
            if (mError)
                return mTrimmedMsg.c_str();
            
            return NULL;
        }
        
    protected:
        AbstractOutputStreamBuffer<> &mRelayStream;
        std::string mTrimmedMsg;
        bool mError;
    };
    
public:
    AbstractDBInterface(
        AbstractOutputStreamBuffer<> *inInfoBuffer,
        AbstractOutputStreamBuffer<> *inErrorBuffer)
    :   out(inInfoBuffer),
        err(inErrorBuffer),
        mArmadilloOutputStreamBuffer(*inErrorBuffer),
        mArmadilloOut(&mArmadilloOutputStreamBuffer) { }
    
    virtual ~AbstractDBInterface() { }
    
    /**
     * @brief Return the memory allocator for this DBMS backend
     * @param inMemContext Memory context the returned allocator shall use.
     *
     * @internal This function should be allowed to have side effects, so we do
     *     not declare it as const.
     */
    virtual AllocatorSPtr allocator(
        AbstractAllocator::Context inMemContext = AbstractAllocator::kFunction,
        AbstractAllocator::ZeroMemory inZeroMemory = AbstractAllocator::kDoNotZero)
        = 0;
    
    /**
     * @brief Return the last error message that did not cause an exception (if any).
     * 
     * Subclasses should call this methods as first step, and only if the return
     * value is NULL, they may report own last errors.
     *
     * The implementation in AbstractDBInterface only checks for errors
     * reported by Armadillo.
     *
     * @see ArmadilloOutputStreamBuffer
     */
    virtual const char *lastError() {
        return mArmadilloOutputStreamBuffer.error();
    }
    
    std::ostream out;
    std::ostream err;
    
protected:
    ArmadilloOutputStreamBuffer mArmadilloOutputStreamBuffer;
    std::ostream mArmadilloOut;
};
