/*
 * 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.
 */

#include <log4cxx/helpers/charsetencoder.h>
#include "../logunit.h"
#include "../insertwide.h"
#include <log4cxx/helpers/bytebuffer.h>
#include <apr.h>
#include <apr_atomic.h>
#include <mutex>
#include <condition_variable>
#include <thread>

using namespace log4cxx;
using namespace log4cxx::helpers;


LOGUNIT_CLASS(CharsetEncoderTestCase)
{
	LOGUNIT_TEST_SUITE(CharsetEncoderTestCase);
	LOGUNIT_TEST(encode1);
	LOGUNIT_TEST(encode2);
	LOGUNIT_TEST(encode3);
	LOGUNIT_TEST(encode4);
#if APR_HAS_THREADS
	LOGUNIT_TEST(thread1);
#endif
	LOGUNIT_TEST_SUITE_END();

	enum { BUFSIZE = 256 };

public:


	void encode1()
	{
		const LogString greeting(LOG4CXX_STR("Hello, World"));
		CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("US-ASCII")));
		char buf[BUFSIZE];
		ByteBuffer out(buf, BUFSIZE);
		LogString::const_iterator iter = greeting.begin();
		log4cxx_status_t stat = enc->encode(greeting, iter, out);
		LOGUNIT_ASSERT_EQUAL(APR_SUCCESS, stat);
		LOGUNIT_ASSERT(iter == greeting.end());

		stat = enc->encode(greeting, iter, out);
		LOGUNIT_ASSERT_EQUAL(APR_SUCCESS, stat);
		LOGUNIT_ASSERT_EQUAL((size_t) 12, out.position());

		out.flip();
		std::string encoded((const char*) out.data(), out.limit());
		LOGUNIT_ASSERT_EQUAL((std::string) "Hello, World", encoded);
		LOGUNIT_ASSERT(iter == greeting.end());
	}

	void encode2()
	{
		LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
		greeting.append(LOG4CXX_STR("Hello"));

		CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("US-ASCII")));

		char buf[BUFSIZE];
		ByteBuffer out(buf, BUFSIZE);
		LogString::const_iterator iter = greeting.begin();
		log4cxx_status_t stat = enc->encode(greeting, iter, out);
		LOGUNIT_ASSERT_EQUAL(APR_SUCCESS, stat);
		LOGUNIT_ASSERT_EQUAL((size_t) 0, out.remaining());
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR('o'), *(iter + 1));

		out.flip();
		std::string encoded((char*) out.data(), out.limit());
		out.clear();

		stat = enc->encode(greeting, iter, out);
		LOGUNIT_ASSERT_EQUAL(APR_SUCCESS, stat);
		LOGUNIT_ASSERT_EQUAL((size_t) 2, out.position());
		LOGUNIT_ASSERT(iter == greeting.end());

		stat = enc->encode(greeting, iter, out);
		out.flip();
		LOGUNIT_ASSERT_EQUAL(APR_SUCCESS, stat);
		encoded.append(out.data(), out.limit());

		std::string manyAs(BUFSIZE - 3, 'A');
		LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
		LOGUNIT_ASSERT_EQUAL(std::string("Hello"), encoded.substr(BUFSIZE - 3));
	}


	void encode3()
	{
#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
		//   arbitrary, hopefully meaningless, characters from
		//     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
		const logchar greet[] = { L'A', 0x0605, 0x0530, 0x986, 0x4E03, 0x400, 0 };
#endif

#if LOG4CXX_LOGCHAR_IS_UTF8
		const char greet[] = { 'A',
				(char) 0xD8, (char) 0x85,
				(char) 0xD4, (char) 0xB0,
				(char) 0xE0, (char) 0xA6, (char) 0x86,
				(char) 0xE4, (char) 0xB8, (char) 0x83,
				(char) 0xD0, (char) 0x80,
				0
			};
#endif
		LogString greeting(greet);

		CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("US-ASCII")));

		char buf[BUFSIZE];
		ByteBuffer out(buf, BUFSIZE);

		LogString::const_iterator iter = greeting.begin();
		log4cxx_status_t stat = enc->encode(greeting, iter, out);
		out.flip();
		LOGUNIT_ASSERT_EQUAL(true, CharsetEncoder::isError(stat));
		LOGUNIT_ASSERT_EQUAL((size_t) 1, out.limit());
		LOGUNIT_ASSERT_EQUAL(greet[1], *iter);
		LOGUNIT_ASSERT_EQUAL('A', out.data()[0]);
	}


	void encode4()
	{
		const char utf8_greet[] = { 'A',
				(char) 0xD8, (char) 0x85,
				(char) 0xD4, (char) 0xB0,
				(char) 0xE0, (char) 0xA6, (char) 0x86,
				(char) 0xE4, (char) 0xB8, (char) 0x83,
				(char) 0xD0, (char) 0x80,
				0
			};
#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
		//   arbitrary, hopefully meaningless, characters from
		//     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
		const logchar greet[] = { L'A', 0x0605, 0x0530, 0x986, 0x4E03, 0x400, 0 };
#endif

#if LOG4CXX_LOGCHAR_IS_UTF8
		const logchar* greet = utf8_greet;
#endif
		LogString greeting(greet);

		CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("UTF-8")));

		char buf[BUFSIZE];
		ByteBuffer out(buf, BUFSIZE);
		LogString::const_iterator iter = greeting.begin();
		log4cxx_status_t stat = enc->encode(greeting, iter, out);
		LOGUNIT_ASSERT_EQUAL(false, CharsetEncoder::isError(stat));
		stat = enc->encode(greeting, iter, out);
		LOGUNIT_ASSERT_EQUAL(false, CharsetEncoder::isError(stat));

		out.flip();
		LOGUNIT_ASSERT_EQUAL((size_t) 13, out.limit());

		for (size_t i = 0; i < out.limit(); i++)
		{
			LOGUNIT_ASSERT_EQUAL((int) utf8_greet[i], (int) out.data()[i]);
		}

		LOGUNIT_ASSERT(iter == greeting.end());
	}

#if APR_HAS_THREADS
	class ThreadPackage
	{
		public:
			ThreadPackage(CharsetEncoderPtr& enc, int repetitions) :
                p(), passCount(0), failCount(0), enc(enc), repetitions(repetitions)
			{
			}

			void await()
			{
                std::unique_lock sync(lock);
                condition.wait(sync);
			}

			void signalAll()
			{
                std::unique_lock sync(lock);
                condition.notify_all();
			}

			void fail()
			{
				apr_atomic_inc32(&failCount);
			}

			void pass()
			{
				apr_atomic_inc32(&passCount);
			}

			apr_uint32_t getFail()
			{
				return apr_atomic_read32(&failCount);
			}

			apr_uint32_t getPass()
			{
				return apr_atomic_read32(&passCount);
			}

			int getRepetitions()
			{
				return repetitions;
			}

			CharsetEncoderPtr& getEncoder()
			{
				return enc;
			}

            void run()
            {
        #if LOG4CXX_LOGCHAR_IS_UTF8
                const logchar greet[] = { 'H', 'e', 'l', 'l', 'o', ' ',
                        (char) 0xC2, (char) 0xA2,  //  cent sign
                        (char) 0xC2, (char) 0xA9,  //  copyright
                        (char) 0xc3, (char) 0xb4,  //  latin small letter o with circumflex
                        0
                    };
        #endif
        #if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
                //   arbitrary, hopefully meaningless, characters from
                //     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
                const logchar greet[] = { L'H', L'e', L'l', L'l', L'o', L' ',
                        0x00A2, 0x00A9, 0x00F4, 0
                    };
        #endif

                const char expected[] =  { 'H', 'e', 'l', 'l', 'o', ' ',
                        (char) 0x00A2, (char) 0x00A9, (char) 0x00F4
                    };

                LogString greeting(greet);

                await();

                for (int i = 0; i < getRepetitions(); i++)
                {
                    bool pass = true;
                    char buf[BUFSIZE];
                    ByteBuffer out(buf, BUFSIZE);
                    LogString::const_iterator iter = greeting.begin();
                    log4cxx_status_t stat = getEncoder()->encode(greeting, iter, out);
                    pass = (false == CharsetEncoder::isError(stat));

                    if (pass)
                    {
                        stat = getEncoder()->encode(greeting, iter, out);
                        pass = (false == CharsetEncoder::isError(stat));

                        if (pass)
                        {
                            out.flip();
                            pass = (sizeof(expected) == out.limit());

                            for (size_t i = 0; i < out.limit() && pass; i++)
                            {
                                pass = (expected[i] == out.data()[i]);
                            }

                            pass = pass && (iter == greeting.end());
                        }
                    }

                    if (pass)
                    {
                        ThreadPackage::pass();
                    }
                    else
                    {
                        fail();
                    }
                }
            }

		private:
			ThreadPackage(const ThreadPackage&);
			ThreadPackage& operator=(ThreadPackage&);
			Pool p;
            std::mutex lock;
            std::condition_variable condition;
			volatile apr_uint32_t passCount;
			volatile apr_uint32_t failCount;
			CharsetEncoderPtr enc;
			int repetitions;
	};

	void thread1()
	{
		enum { THREAD_COUNT = 10, THREAD_REPS = 10000 };
        std::thread threads[THREAD_COUNT];
		CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("ISO-8859-1")));
		ThreadPackage* package = new ThreadPackage(enc, THREAD_REPS);
		{
			for (int i = 0; i < THREAD_COUNT; i++)
			{
                threads[i] = std::thread(&ThreadPackage::run, package);
			}
		}
		//
		//   give time for all threads to be launched so
        //      we don't signal before everybody is waiting.
        std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
		package->signalAll();

		for (int i = 0; i < THREAD_COUNT; i++)
		{
			threads[i].join();
		}

		LOGUNIT_ASSERT_EQUAL((apr_uint32_t) 0, package->getFail());
		LOGUNIT_ASSERT_EQUAL((apr_uint32_t) THREAD_COUNT * THREAD_REPS, package->getPass());
		delete package;
	}
#endif

};

LOGUNIT_TEST_SUITE_REGISTRATION(CharsetEncoderTestCase);
