/*
 * 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_CONSTANT_MACROS
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/cacheddateformat.h>


#include <apr_time.h>
#include <log4cxx/helpers/pool.h>
#include <limits>
#include <log4cxx/helpers/exception.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::pattern;




/**
*  Supported digit set.  If the wrapped DateFormat uses
*  a different unit set, the millisecond pattern
*  will not be recognized and duplicate requests
*  will use the cache.
*/
const logchar CachedDateFormat::digits[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0 };


/**
 * First magic number (in microseconds) used to detect
 * the millisecond position.
 */
const int CachedDateFormat::magic1 = 654000;


/**
 *  Expected representation of first magic number in milliseconds.
 */
const logchar CachedDateFormat::magicString1[] = { 0x36, 0x35, 0x34, 0 };


/**
 * Second magic number (in microseconds) used to detect
 * the millisecond position.
 */
const int CachedDateFormat::magic2 = 987000;


/**
 *  Expected representation of second magic number in milliseconds.
 */
const logchar CachedDateFormat::magicString2[] = { 0x39, 0x38, 0x37, 0};


/**
 *  Expected representation of 0 milliseconds.
 */
const logchar CachedDateFormat::zeroString[] = { 0x30, 0x30, 0x30, 0 };

#undef min

/**
 *  Creates a new CachedDateFormat object.
 *  @param dateFormat Date format, may not be null.
 *  @param expiration maximum cached range in milliseconds.
 *    If the dateFormat is known to be incompatible with the
 *      caching algorithm, use a value of 0 to totally disable
 *      caching or 1 to only use cache for duplicate requests.
 */
CachedDateFormat::CachedDateFormat(const DateFormatPtr& dateFormat,
	int expiration1) :
	formatter(dateFormat),
	millisecondStart(0),
	slotBegin(std::numeric_limits<log4cxx_time_t>::min()),
	cache(50, 0x20),
	expiration(expiration1),
	previousTime(std::numeric_limits<log4cxx_time_t>::min())
{
	if (dateFormat == NULL)
	{
		throw IllegalArgumentException(LOG4CXX_STR("dateFormat cannot be null"));
	}

	if (expiration1 < 0)
	{
		throw IllegalArgumentException(LOG4CXX_STR("expiration must be non-negative"));
	}
}


/**
 * Finds start of millisecond field in formatted time.
 * @param time long time, must be integral number of seconds
 * @param formatted String corresponding formatted string
 * @param formatter DateFormat date format
 * @return int position in string of first digit of milliseconds,
 *    -1 indicates no millisecond field, -2 indicates unrecognized
 *    field (likely RelativeTimeDateFormat)
 */
int CachedDateFormat::findMillisecondStart(
	log4cxx_time_t time, const LogString& formatted,
	const DateFormatPtr& formatter,
	Pool& pool)
{

	apr_time_t slotBegin = (time / 1000000) * 1000000;

	if (slotBegin > time)
	{
		slotBegin -= 1000000;
	}

	int millis = (int) (time - slotBegin) / 1000;

	// the magic numbers are in microseconds
	int magic = magic1;
	LogString magicString(magicString1);

	if (millis == magic1 / 1000)
	{
		magic = magic2;
		magicString = magicString2;
	}

	LogString plusMagic;
	formatter->format(plusMagic, slotBegin + magic, pool);

	/**
	 *   If the string lengths differ then
	 *      we can't use the cache except for duplicate requests.
	 */
	if (plusMagic.length() != formatted.length())
	{
		return UNRECOGNIZED_MILLISECONDS;
	}
	else
	{
		// find first difference between values
		for (LogString::size_type i = 0; i < formatted.length(); i++)
		{
			if (formatted[i] != plusMagic[i])
			{
				//
				//   determine the expected digits for the base time
				const logchar abc[] = { 0x41, 0x42, 0x43, 0 };
				LogString formattedMillis(abc);
				millisecondFormat(millis, formattedMillis, 0);

				LogString plusZero;
				formatter->format(plusZero, slotBegin, pool);

				// Test if the next 1..3 characters match the magic string, main problem is that magic
				// available millis in formatted can overlap. Therefore the current i is not always the
				// index of the first millis char, but may be already within the millis. Besides that
				// the millis can occur everywhere in formatted. See LOGCXX-420 and following.
				size_t  magicLength     = magicString.length();
				size_t  overlapping     = magicString.find(plusMagic[i]);
				int     possibleRetVal  = i - overlapping;

				if (plusZero.length() == formatted.length()
					&& regionMatches(magicString,       0, plusMagic,   possibleRetVal, magicLength)
					&& regionMatches(formattedMillis,   0, formatted,   possibleRetVal, magicLength)
					&& regionMatches(zeroString,        0, plusZero,    possibleRetVal, magicLength)
					// The following will and should fail for patterns with more than one SSS because
					// we only seem to be able to change one SSS in e.g. format and need to reformat the
					// whole string in other cases.
					&& (formatted.length() == possibleRetVal + magicLength
						|| plusZero.compare(possibleRetVal + magicLength,
							LogString::npos, plusMagic, possibleRetVal + magicLength, LogString::npos) == 0))
				{
					return possibleRetVal;
				}
				else
				{
					return UNRECOGNIZED_MILLISECONDS;
				}
			}
		}
	}

	return NO_MILLISECONDS;
}


/**
 * Formats a millisecond count into a date/time string.
 *
 *  @param now Number of milliseconds after midnight 1 Jan 1970 GMT.
 *  @param sbuf the string buffer to write to
 */
void CachedDateFormat::format(LogString& buf, log4cxx_time_t now, Pool& p) const
{

	//
	// If the current requested time is identical to the previously
	//     requested time, then append the cache contents.
	//
	if (now == previousTime)
	{
		buf.append(cache);
		return;
	}

	//
	//   If millisecond pattern was not unrecognized
	//     (that is if it was found or milliseconds did not appear)
	//
	if (millisecondStart != UNRECOGNIZED_MILLISECONDS)
	{
		//    Check if the cache is still valid.
		//    If the requested time is within the same integral second
		//       as the last request and a shorter expiration was not requested.
		if (now < slotBegin + expiration
			&& now >= slotBegin
			&& now < slotBegin + 1000000L)
		{
			//
			//    if there was a millisecond field then update it
			//
			if (millisecondStart >= 0)
			{
				millisecondFormat((int) ((now - slotBegin) / 1000), cache, millisecondStart);
			}

			//
			//   update the previously requested time
			//      (the slot begin should be unchanged)
			previousTime = now;
			buf.append(cache);

			return;
		}
	}

	//
	//  could not use previous value.
	//    Call underlying formatter to format date.
	cache.erase(cache.begin(), cache.end());
	formatter->format(cache, now, p);
	buf.append(cache);
	previousTime = now;
	slotBegin = (previousTime / 1000000) * 1000000;

	if (slotBegin > previousTime)
	{
		slotBegin -= 1000000;
	}

	//
	//    if the milliseconds field was previous found
	//       then reevaluate in case it moved.
	//
	if (millisecondStart >= 0)
	{
		millisecondStart = findMillisecondStart(now, cache, formatter, p);
	}
}

/**
 *   Formats a count of milliseconds (0-999) into a numeric representation.
 *   @param millis Millisecond count between 0 and 999.
 *   @buf String buffer, may not be null.
 *   @offset Starting position in buffer, the length of the
 *       buffer must be at least offset + 3.
 */
void CachedDateFormat::millisecondFormat(int millis,
	LogString& buf,
	int offset)
{
	buf[offset] = digits[millis / 100];
	buf[offset + 1] = digits[(millis / 10) % 10];
	buf[offset + 2] = digits[millis  % 10];
}

/**
 * Set timezone.
 *
 * @remarks Setting the timezone using getCalendar().setTimeZone()
 * will likely cause caching to misbehave.
 * @param timeZone TimeZone new timezone
 */
void CachedDateFormat::setTimeZone(const TimeZonePtr& timeZone)
{
	formatter->setTimeZone(timeZone);
	previousTime = std::numeric_limits<log4cxx_time_t>::min();
	slotBegin = std::numeric_limits<log4cxx_time_t>::min();
}



void CachedDateFormat::numberFormat(LogString& s, int n, Pool& p) const
{
	formatter->numberFormat(s, n, p);
}


/**
 * Gets maximum cache validity for the specified SimpleDateTime
 *    conversion pattern.
 *  @param pattern conversion pattern, may not be null.
 *  @returns Duration in microseconds from an integral second
 *      that the cache will return consistent results.
 */
int CachedDateFormat::getMaximumCacheValidity(const LogString& pattern)
{
	//
	//   If there are more "S" in the pattern than just one "SSS" then
	//      (for example, "HH:mm:ss,SSS SSS"), then set the expiration to
	//      one millisecond which should only perform duplicate request caching.
	//
	const logchar S = 0x53;
	const logchar SSS[] = { 0x53, 0x53, 0x53, 0 };
	size_t firstS = pattern.find(S);
	size_t len = pattern.length();

	//
	//   if there are no S's or
	//      three that start with the first S and no fourth S in the string
	//
	if (firstS == LogString::npos ||
		(len >= firstS + 3 && pattern.compare(firstS, 3, SSS) == 0
			&& (len == firstS + 3 ||
				pattern.find(S, firstS + 3) == LogString::npos)))
	{
		return 1000000;
	}

	return 1000;
}


/**
* Tests if two string regions are equal.
* @param target target string.
* @param toffset character position in target to start comparison.
* @param other other string.
* @param ooffset character position in other to start comparison.
* @param len length of region.
* @return true if regions are equal.
*/
bool CachedDateFormat::regionMatches(
	const LogString& target,
	size_t toffset,
	const LogString& other,
	size_t ooffset,
	size_t len)
{
	return target.compare(toffset, len, other, ooffset, len) == 0;
}

