/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
#if defined(_MSC_VER)
#pragma warning ( disable: 4231 4251 4275 4786 )
#endif

#include "logunit.h"

#include <apr_general.h>
#include <algorithm>
#include <stdlib.h>
#include <locale.h>

void initialize() {
    setlocale(LC_CTYPE, "");
    const char* ctype = setlocale(LC_CTYPE, 0);
    if (ctype == 0) {
        puts("LC_CTYPE: NULL");
    } else {
        printf("LC_CTYPE: %s\n", ctype);
    }
    apr_initialize();
}

extern const char** testlist;

static bool suite_sort(const LogUnit::SuiteList::value_type& lhs, const LogUnit::SuiteList::value_type& rhs) {
    return lhs.first < rhs.first;
}

abts_suite* abts_run_suites(abts_suite* suite) {
    LogUnit::SuiteList sorted(LogUnit::getAllSuites());

#if !defined(_MSC_VER)
    std::sort(sorted.begin(), sorted.end(), suite_sort);
#endif
    
    for(LogUnit::SuiteList::const_iterator iter = sorted.begin();
        iter != sorted.end();
        iter++) {
        //
        //   if there is an explicit testlist or if the suite is not by default disabled
        //         pump suite through filter
        if(testlist || !iter->second->isDisabled()) {
            suite = iter->second->run(suite);
        }
    }
    apr_terminate();
    return suite;
}

using namespace LogUnit;
using namespace std;

TestException::TestException() {}
TestException::TestException(const TestException& src) : std::exception(src) {
}

TestException& TestException::operator=(const TestException& src) {
    exception::operator=(src);
    return *this;
}


AssertException::AssertException(std::string message, int line) : msg(message), lineno(line) {}

AssertException::AssertException(bool expected, const char* actualExpr, int line) : msg(actualExpr), lineno(line) {
   if (expected) {
        msg.append(" was expected to be true, was false.");
   } else {
        msg.append(" was expected to be true, was false.");
   }
}

AssertException::AssertException(const AssertException& src) 
    : std::exception(src), 
      msg(src.msg), 
     lineno(src.lineno) {
}

AssertException::~AssertException() throw() {
}

AssertException& AssertException::operator=(const AssertException& src) {
    exception::operator=(src);
    msg = src.msg;
    lineno = src.lineno;
    return *this;
}

std::string AssertException::getMessage() const {
    return msg;
}

int AssertException::getLine() const {
    return lineno;
}




TestFixture::TestFixture() : tc(0) {}
TestFixture::~TestFixture() {}
void TestFixture::setCase(abts_case* newtc) {
      tc = newtc;
}
void TestFixture::setUp() {}
void TestFixture::tearDown() {}

void TestFixture::assertEquals(const char* expected, 
     const char* actual, 
     const char* expectedExpr,
     const char* actualExpr,
     int lineno) {
    abts_str_equal(tc, expected, actual, lineno);
    if ((expected == 0 || actual != 0) ||
        (expected != 0 || actual == 0) ||
        (expected != 0 && strcmp(expected, actual) != 0)) {
        throw TestException();
    }
}

void TestFixture::assertEquals(const std::string expected, 
     const std::string actual, 
     const char* expectedExpr,
     const char* actualExpr,
     int lineno) {
    abts_str_equal(tc, expected.c_str(), actual.c_str(), lineno);
    if (expected != actual) {
        throw TestException();
    }
}

template<class S>
static void transcode(std::string& dst, const S& src) {
        for(typename S::const_iterator iter = src.begin();
            iter != src.end();
            iter++) {
            if (*iter <= 0x7F) {
                dst.append(1, (char) *iter);
             } else {
                dst.append(1, '?');
            }
        }
}

#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_WCHAR_T_API       
void TestFixture::assertEquals(const std::wstring expected, 
    const std::wstring actual, 
    const char* expectedExpr,
    const char* actualExpr,
    int lineno) {
    if (expected != actual) {
        std::string exp, act;
      transcode(exp, expected);
      transcode(act, actual);
        abts_str_equal(tc, exp.c_str(), act.c_str(), lineno);
        throw TestException();
    }
}
#endif        
#if LOG4CXX_LOGCHAR_IS_UNICHAR || LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
void TestFixture::assertEquals(const std::basic_string<log4cxx::UniChar> expected, 
     const std::basic_string<log4cxx::UniChar> actual,      
     const char* expectedExpr,
     const char* actualExpr,
int lineno) {
    if (expected != actual) {
        std::string exp, act;
      transcode(exp, expected);
      transcode(act, actual);
        abts_str_equal(tc, exp.c_str(), act.c_str(), lineno);
        throw TestException();
    }
}
#endif        


void TestFixture::assertEquals(const int expected, const int actual, int lineno) {
    abts_int_equal(tc, expected, actual, lineno);
    if (expected != actual) {
        throw TestException();
    }
}


LogUnit::TestSuite::TestSuite(const char* fname) : filename(fname), disabled(false) {
#if defined(_WIN32)
    for(size_t i = filename.find('\\');
        i != std::string::npos;
        i = filename.find('\\', i+1)) {
        filename.replace(i, 1, 1, '/');
    }
#endif
}

void LogUnit::TestSuite::addTest(const char*, test_func func) {
   test_funcs.push_back(func);
}

std::string LogUnit::TestSuite::getName() const {
   return filename;
}

void LogUnit::TestSuite::setDisabled(bool newVal) {
    disabled = newVal;
}

bool LogUnit::TestSuite::isDisabled() const {
    return disabled;
}

abts_suite* TestSuite::run(abts_suite* suite) const {
    suite = abts_add_suite(suite, filename.c_str());
    for(TestList::const_iterator iter = test_funcs.begin();
        iter != test_funcs.end();
        iter++) {
        abts_run_test(suite, *iter, NULL);
    }
    return suite;
}


LogUnit::SuiteList& LogUnit::getAllSuites() {
    static LogUnit::SuiteList allSuites;
    return allSuites;
}

