/*
 * 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;
}

