/*
 * 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.
 */
#define __STDC_WANT_LIB_EXT1__ 1
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/exception.h>
#include <string.h>
#include <string>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/pool.h>
#include <apr_errno.h>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;

Exception::Exception(const LogString& msg1)
{
	LOG4CXX_ENCODE_CHAR(m, msg1);
	size_t len = m.size();

	if (len > MSG_SIZE)
	{
		len = MSG_SIZE;
	}

#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	memcpy_s(msg, sizeof msg, m.data(), len);
#else
	memcpy(msg, m.data(), len);
#endif
	msg[len] = 0;
}

Exception::Exception(const char* m)
{
#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	strncpy_s(msg, sizeof msg, m, MSG_SIZE);
#else
	strncpy(msg, m, MSG_SIZE);
#endif
	msg[MSG_SIZE] = 0;
}


Exception::Exception(const Exception& src) : std::exception()
{
#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	strcpy_s(msg, sizeof msg, src.msg);
#else
	strncpy(msg, src.msg, MSG_SIZE);
	msg[MSG_SIZE] = 0;
#endif
}

Exception& Exception::operator=(const Exception& src)
{
#if defined(__STDC_LIB_EXT1__) || defined(__STDC_SECURE_LIB__)
	strcpy_s(msg, sizeof msg, src.msg);
#else
	strncpy(msg, src.msg, MSG_SIZE);
	msg[MSG_SIZE] = 0;
#endif
	return *this;
}

const char* Exception::what() const throw()
{
	return msg;
}

RuntimeException::RuntimeException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

RuntimeException::RuntimeException(const LogString& msg1)
	: Exception(msg1)
{
}

RuntimeException::RuntimeException(const RuntimeException& src)
	: Exception(src)
{
}

RuntimeException& RuntimeException::operator=(const RuntimeException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString RuntimeException::formatMessage(log4cxx_status_t stat)
{
	LogString s(LOG4CXX_STR("RuntimeException: return code = "));
	Pool p;
	StringHelper::toString(stat, p, s);
	return s;
}

NullPointerException::NullPointerException(const LogString& msg1)
	: RuntimeException(msg1)
{
}

NullPointerException::NullPointerException(const NullPointerException& src)
	: RuntimeException(src)
{
}

NullPointerException& NullPointerException::operator=(const NullPointerException& src)
{
	RuntimeException::operator=(src);
	return *this;
}

IllegalArgumentException::IllegalArgumentException(const LogString& msg1)
	: RuntimeException(msg1)
{
}

IllegalArgumentException::IllegalArgumentException(const IllegalArgumentException& src)
	: RuntimeException(src)
{
}

IllegalArgumentException& IllegalArgumentException::operator=(const IllegalArgumentException& src)
{
	RuntimeException::operator=(src);
	return *this;
}

IOException::IOException()
	: Exception(LOG4CXX_STR("IO exception"))
{
}

IOException::IOException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

IOException::IOException(const LogString& type, log4cxx_status_t stat)
	: Exception(makeMessage(type, stat))
{
}


IOException::IOException(const LogString& msg1)
	: Exception(msg1)
{
}

IOException::IOException(const IOException& src)
	: Exception(src)
{
}

IOException& IOException::operator=(const IOException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString IOException::formatMessage(log4cxx_status_t stat)
{
	return makeMessage(LOG4CXX_STR("IO Exception"), stat);
}

LogString Exception::makeMessage(const LogString& type, log4cxx_status_t stat)
{
	LogString s = type;
	char err_buff[1024] = {0};
	apr_strerror(stat, err_buff, sizeof(err_buff));
	if (0 == err_buff[0] || 0 == strncmp(err_buff, "APR does not understand", 23))
	{
		s.append(LOG4CXX_STR(": error code "));
		Pool p;
		StringHelper::toString(stat, p, s);
	}
	else
	{
		s.append(LOG4CXX_STR(" - "));
		std::string sMsg = err_buff;
		LOG4CXX_DECODE_CHAR(lsMsg, sMsg);
		s.append(lsMsg);
	}
	return s;
}


MissingResourceException::MissingResourceException(const LogString& key)
	: Exception(formatMessage(key))
{
}


MissingResourceException::MissingResourceException(const MissingResourceException& src)
	: Exception(src)
{
}

MissingResourceException& MissingResourceException::operator=(const MissingResourceException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString MissingResourceException::formatMessage(const LogString& key)
{
	LogString s(LOG4CXX_STR("MissingResourceException: resource key = \""));
	s.append(key);
	s.append(LOG4CXX_STR("\"."));
	return s;
}

PoolException::PoolException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

PoolException::PoolException(const PoolException& src)
	: Exception(src)
{
}

PoolException& PoolException::operator=(const PoolException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString PoolException::formatMessage(log4cxx_status_t stat)
{
	return makeMessage(LOG4CXX_STR("Pool exception"), stat);
}


TranscoderException::TranscoderException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

TranscoderException::TranscoderException(const TranscoderException& src)
	: Exception(src)
{
}

TranscoderException& TranscoderException::operator=(const TranscoderException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString TranscoderException::formatMessage(log4cxx_status_t)
{
	return LOG4CXX_STR("Transcoder exception");
}


InterruptedException::InterruptedException() : Exception(LOG4CXX_STR("Thread was interrupted"))
{
}

InterruptedException::InterruptedException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

InterruptedException::InterruptedException(const InterruptedException& src)
	: Exception(src)
{
}

InterruptedException& InterruptedException::operator=(const InterruptedException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString InterruptedException::formatMessage(log4cxx_status_t stat)
{
	LogString s(LOG4CXX_STR("InterruptedException: stat = "));
	Pool p;
	StringHelper::toString(stat, p, s);
	return s;
}

ThreadException::ThreadException(log4cxx_status_t stat)
	: Exception(formatMessage(stat))
{
}

ThreadException::ThreadException(const LogString& msg)
	: Exception(msg)
{
}

ThreadException::ThreadException(const ThreadException& src)
	: Exception(src)
{
}

ThreadException& ThreadException::operator=(const ThreadException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString ThreadException::formatMessage(log4cxx_status_t stat)
{
	return makeMessage(LOG4CXX_STR("Thread exception"), stat);
}

IllegalMonitorStateException::IllegalMonitorStateException(const LogString& msg1)
	: Exception(msg1)
{
}

IllegalMonitorStateException::IllegalMonitorStateException(const IllegalMonitorStateException& src)
	: Exception(src)
{
}

IllegalMonitorStateException& IllegalMonitorStateException::operator=(const IllegalMonitorStateException& src)
{
	Exception::operator=(src);
	return *this;
}

InstantiationException::InstantiationException(const LogString& msg1)
	: Exception(msg1)
{
}

InstantiationException::InstantiationException(const InstantiationException& src)
	: Exception(src)
{
}

InstantiationException& InstantiationException::operator=(const InstantiationException& src)
{
	Exception::operator=(src);
	return *this;
}

ClassNotFoundException::ClassNotFoundException(const LogString& className)
	: Exception(formatMessage(className))
{
}

ClassNotFoundException::ClassNotFoundException(const ClassNotFoundException& src)
	: Exception(src)
{
}


ClassNotFoundException& ClassNotFoundException::operator=(const ClassNotFoundException& src)
{
	Exception::operator=(src);
	return *this;
}

LogString ClassNotFoundException::formatMessage(const LogString& className)
{
	LogString s(LOG4CXX_STR("Class not found: "));
	s.append(className);
	return s;
}


NoSuchElementException::NoSuchElementException()
	: Exception(LOG4CXX_STR("No such element"))
{
}

NoSuchElementException::NoSuchElementException(const NoSuchElementException& src)
	: Exception(src)
{
}

NoSuchElementException& NoSuchElementException::operator=(const NoSuchElementException& src)
{
	Exception::operator=(src);
	return *this;
}


IllegalStateException::IllegalStateException()
	: Exception(LOG4CXX_STR("Illegal state"))
{
}

IllegalStateException::IllegalStateException(const IllegalStateException& src)
	: Exception(src)
{
}

IllegalStateException& IllegalStateException::operator=(const IllegalStateException& src)
{
	Exception::operator=(src);
	return *this;
}

SocketException::SocketException(const LogString& msg) : IOException(msg)
{
}

SocketException::SocketException(log4cxx_status_t status) : IOException(status)
{
}

SocketException::SocketException(const SocketException& src)
	: IOException(src)
{
}

SocketException& SocketException::operator=(const SocketException& src)
{
	IOException::operator=(src);
	return *this;
}

ConnectException::ConnectException(log4cxx_status_t status) : SocketException(status)
{
}

ConnectException::ConnectException(const ConnectException& src)
	: SocketException(src)
{
}

ConnectException& ConnectException::operator=(const ConnectException& src)
{
	SocketException::operator=(src);
	return *this;
}

ClosedChannelException::ClosedChannelException() : SocketException(LOG4CXX_STR("Attempt to write to closed socket"))
{
}

ClosedChannelException::ClosedChannelException(const ClosedChannelException& src)
	: SocketException(src)
{
}

ClosedChannelException& ClosedChannelException::operator=(const ClosedChannelException& src)
{
	SocketException::operator=(src);
	return *this;
}

BindException::BindException(log4cxx_status_t status) : SocketException(status)
{
}

BindException::BindException(const BindException& src)
	: SocketException(src)
{
}

BindException& BindException::operator=(const BindException& src)
{
	SocketException::operator=(src);
	return *this;
}

InterruptedIOException::InterruptedIOException(const LogString& msg) : IOException(msg)
{
}

InterruptedIOException::InterruptedIOException(const InterruptedIOException& src)
	: IOException(src)
{
}

InterruptedIOException& InterruptedIOException::operator=(const InterruptedIOException& src)
{
	IOException::operator=(src);
	return *this;
}

SocketTimeoutException::SocketTimeoutException()
	: InterruptedIOException(LOG4CXX_STR("SocketTimeoutException"))
{
}

SocketTimeoutException::SocketTimeoutException(const SocketTimeoutException& src)
	: InterruptedIOException(src)
{
}

SocketTimeoutException& SocketTimeoutException::operator=(const SocketTimeoutException& src)
{
	InterruptedIOException::operator=(src);
	return *this;
}
