//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_assertion_only.hpp
 * @brief       assertion のみ利用するためのファイル
 * @deprecated
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_ASSERTION_ONLY_HPP_9E5FA1C8_EFB5_40A9_A3AD_971584ECAE56_
#define INCG_IRIS_IUTEST_ASSERTION_ONLY_HPP_9E5FA1C8_EFB5_40A9_A3AD_971584ECAE56_

#if !defined(IUTEST_USE_GTEST)

#else // !defined(IUTEST_USE_GTEST)

#include "iutest_gtest_ver.hpp"
#if GTEST_OS_WINDOWS
#include <windows.h>
#endif

namespace testing
{

#if   GTEST_MAJORVER > 1 || GTEST_MINORVER >= 0x07
typedef ::std::string               GTestAssertionResultString;
typedef ::std::string               GTestString;
#elif GTEST_MINORVER == 0x06
typedef ::std::string               GTestAssertionResultString;
typedef ::testing::internal::String GTestString;
#elif GTEST_MINORVER == 0x05
typedef ::testing::internal::String GTestAssertionResultString;
typedef ::testing::internal::String GTestString;
#else
#  error sorry, google test version 1.4.0 or less is unsupported.
#endif

AssertionResult::AssertionResult(const AssertionResult& other)
    : success_(other.success_)
    , message_(other.message_.get() != NULL ?
    new GTestAssertionResultString(*other.message_) : static_cast< GTestAssertionResultString*>(NULL))
{
}

AssertionResult AssertionResult::operator ! () const
{
    return AssertionResult(success_);
}

AssertionResult AssertionFailure()
{
    return AssertionResult(false);
}

AssertionResult AssertionSuccess()
{
    return AssertionResult(true);
}

namespace internal
{

AssertHelper::AssertHelper(TestPartResult::Type type,
    const char* file,
    int line,
    const char* message)
    : data_(new AssertHelperData(type, file, line, message)) {}
AssertHelper::~AssertHelper()
{
    delete data_;
}

void AssertHelper::operator=(const Message& message) const
{
    Message msg;
#if defined(_MSC_VER)
    msg << data_->file << "(" << data_->line << "): error : " << data_->message << message.GetString() << "\n";
#else
    msg << data_->file << ":" << data_->line << ": error : " << data_->message << message.GetString() << "\n";
#endif

    printf("%s", msg.GetString().c_str());
#if GTEST_OS_WINDOWS
    OutputDebugStringA(msg.GetString().c_str());
#endif
}

bool IsTrue(bool condition) { return condition; }
bool AlwaysTrue() { return true; }

AssertionResult EqFailure(const char* expected_expression,
    const char* actual_expression,
    const GTestString& expected_value,
    const GTestString& actual_value,
    bool ignoring_case)
{
    Message msg;
    msg << "Value of: " << actual_expression;
    if( !String::CStringEquals(actual_value.c_str(), actual_expression) ) {
        msg << "\n  Actual: " << actual_value;
    }

    msg << "\nExpected: " << expected_expression;
    if (ignoring_case) {
        msg << " (ignoring case)";
    }
    if( !String::CStringEquals(expected_value.c_str(), expected_expression) ) {
        msg << "\nWhich is: " << expected_value;
    }

    return AssertionFailure() << msg;
}

#if GTEST_MINORVER <= 0x06
int String::Compare(const String& rhs) const
{
    const char* const lhs_c_str = c_str();
    const char* const rhs_c_str = rhs.c_str();

    if (lhs_c_str == NULL) {
        return rhs_c_str == NULL ? 0 : -1;  // NULL < anything except NULL
    } else if (rhs_c_str == NULL) {
        return 1;
    }

    const size_t shorter_str_len =
        length() <= rhs.length() ? length() : rhs.length();
    for (size_t i = 0; i != shorter_str_len; i++) {
        if (lhs_c_str[i] < rhs_c_str[i]) {
            return -1;
        } else if (lhs_c_str[i] > rhs_c_str[i]) {
            return 1;
        }
    }
    return (length() < rhs.length()) ? -1 :
        (length() > rhs.length()) ? 1 : 0;
}
#endif

bool String::CStringEquals(const char* lhs, const char* rhs)
{
    if( lhs == NULL || rhs == NULL )
    {
        return lhs == rhs;
    }
    return strcmp(lhs, rhs) == 0;
}
bool String::CaseInsensitiveCStringEquals(const char* lhs,
    const char* rhs)
{
    if( lhs == NULL || rhs == NULL )
    {
        return lhs == rhs;
    }
    return internal::posix::StrCaseCmp(lhs, rhs) == 0;
}

namespace impl
{

GTestString ShowCStringQuoted(const char* c_str)
{
    ::std::string s = "\"";
    s += c_str;
    s += "\"";
    return GTestString(s);
}

}   // end of namespace impl

#ifdef GTEST_CREF_WORKAROUND_
String String::ShowCStringQuoted(const char* c_str)
{
    return impl::ShowCStringQuoted(c_str);
}
#endif

GTestString GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
    const char* expression_text,
    const char* actual_predicate_value,
    const char* expected_predicate_value) {
        const char* actual_message = assertion_result.message();
        Message msg;
        msg << "Value of: " << expression_text
            << "\n  Actual: " << actual_predicate_value;
        if (actual_message[0] != '\0')
            msg << " (" << actual_message << ")";
        msg << "\nExpected: " << expected_predicate_value;
        return msg.GetString();
}

GTestString StringStreamToString(::std::stringstream* ss) {
    const ::std::string& str = ss->str();
    const char* const start = str.c_str();
    const char* const end = start + str.length();

    // We need to use a helper stringstream to do this transformation
    // because String doesn't support push_back().
    ::std::stringstream helper;
    for (const char* ch = start; ch != end; ++ch) {
        if (*ch == '\0') {
            helper << "\\0";  // Replaces NUL with "\\0";
        } else {
            helper.put(*ch);
        }
    }

    return GTestString(helper.str().c_str());
}
GTestString StrStreamToString(::std::stringstream* ss) {
    return StringStreamToString(ss);
}

AssertionResult CmpHelperSTREQ(const char* expected_expression,
    const char* actual_expression,
    const char* expected,
    const char* actual) {
        if (String::CStringEquals(expected, actual)) {
            return AssertionSuccess();
        }

        return EqFailure(expected_expression,
            actual_expression,
            impl::ShowCStringQuoted(expected),
            impl::ShowCStringQuoted(actual),
            false);
}

AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
    const char* actual_expression,
    const char* expected,
    const char* actual)
{
    if (String::CaseInsensitiveCStringEquals(expected, actual)) {
        return AssertionSuccess();
    }

    return EqFailure(expected_expression,
        actual_expression,
        impl::ShowCStringQuoted(expected),
        impl::ShowCStringQuoted(actual),
        true);
}

AssertionResult CmpHelperSTRNE(const char* s1_expression,
    const char* s2_expression,
    const char* s1,
    const char* s2)
{
    if (!String::CStringEquals(s1, s2)) {
        return AssertionSuccess();
    } else {
        return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
            << s2_expression << "), actual: \""
            << s1 << "\" vs \"" << s2 << "\"";
    }
}

AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
    const char* s2_expression,
    const char* s1,
    const char* s2) {
        if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
            return AssertionSuccess();
        } else {
            return AssertionFailure()
                << "Expected: (" << s1_expression << ") != ("
                << s2_expression << ") (ignoring case), actual: \""
                << s1 << "\" vs \"" << s2 << "\"";
        }
}

}   // end of namespace internal

#if GTEST_MINORVER >= 0x07
Message::Message() : ss_(new ::std::stringstream) {
    *ss_ << ::std::setprecision(std::numeric_limits<double>::digits10 + 2);
}

::std::string Message::GetString() const {
    return internal::StringStreamToString(ss_.get());
}
#endif

}   // end of namespace testing

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_ASSERTION_ONLY_HPP_9E5FA1C8_EFB5_40A9_A3AD_971584ECAE56_
