/*
 * Copyright (C) 2010 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.
 */

#ifndef A_DEBUG_H_

#define A_DEBUG_H_

#include <string.h>

#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>

namespace android {

enum LogType {
    VERBOSE,
    INFO,
    WARNING,
    ERROR,
    FATAL,
};

struct Logger {
    Logger(LogType type);
    virtual ~Logger();

    template<class T> Logger &operator<<(const T &x) {
        mMessage.append(x);

        return *this;
    }

private:
    android::AString mMessage;
    LogType mLogType;

    DISALLOW_EVIL_CONSTRUCTORS(Logger);
};

const char *LeafName(const char *s);

#undef LOG
#define LOG(type)    Logger(type) << LeafName(__FILE__) << ":" << __LINE__ << " "

#define CHECK(condition)                                \
    do {                                                \
        if (!(condition)) {                             \
            LOG(FATAL) << "CHECK(" #condition ") failed.";    \
        }                                               \
    } while (false)

#define MAKE_COMPARATOR(suffix,op)                          \
    template<class A, class B>                              \
    AString Compare_##suffix(const A &a, const B &b) {      \
        AString res;                                        \
        if (!(a op b)) {                                    \
            res.append(a);                                  \
            res.append(" vs. ");                            \
            res.append(b);                                  \
        }                                                   \
        return res;                                         \
    }

MAKE_COMPARATOR(EQ,==)
MAKE_COMPARATOR(NE,!=)
MAKE_COMPARATOR(LE,<=)
MAKE_COMPARATOR(GE,>=)
MAKE_COMPARATOR(LT,<)
MAKE_COMPARATOR(GT,>)

#define CHECK_OP(x,y,suffix,op)                                         \
    do {                                                                \
        AString ___res = Compare_##suffix(x, y);                        \
        if (!___res.empty()) {                                          \
            LOG(FATAL) << "CHECK_" #suffix "(" #x "," #y ") failed: "   \
                       << ___res;                                       \
        }                                                               \
    } while (false)

#define CHECK_EQ(x,y)   CHECK_OP(x,y,EQ,==)
#define CHECK_NE(x,y)   CHECK_OP(x,y,NE,!=)
#define CHECK_LE(x,y)   CHECK_OP(x,y,LE,<=)
#define CHECK_LT(x,y)   CHECK_OP(x,y,LT,<)
#define CHECK_GE(x,y)   CHECK_OP(x,y,GE,>=)
#define CHECK_GT(x,y)   CHECK_OP(x,y,GT,>)

#define TRESPASS()      LOG(FATAL) << "Should not be here."

}  // namespace android

#endif  // A_DEBUG_H_

