/*
 * 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/logstring.h>
#include <log4cxx/helpers/properties.h>
#include <log4cxx/helpers/inputstreamreader.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/helpers/pool.h>

using namespace log4cxx;
using namespace log4cxx::helpers;

class PropertyParser
{
	public:
		void parse(LogString& in, Properties& properties)
		{
			LogString key, element;
			LexemType lexemType = BEGIN;
			logchar c;
			bool finished = false;

			if (!get(in, c))
			{
				return;
			}

			while (!finished)
			{
				switch (lexemType)
				{
					case BEGIN:
						switch (c)
						{
							case 0x20: // ' '
							case 0x09: // '\t'
							case 0x0A: // '\n'
							case 0x0D: // '\r'
								if (!get(in, c))
								{
									finished = true;
								}

								break;

							case 0x23: // '#'
							case 0x21: // '!'
								lexemType = COMMENT;

								if (!get(in, c))
								{
									finished = true;
								}

								break;

							default:
								lexemType = KEY;
								break;
						}

						break;

					case KEY:
						switch (c)
						{
							case 0x5C: // '\\'
								lexemType = KEY_ESCAPE;

								if (!get(in, c))
								{
									finished = true;
								}

								break;

							case 0x09: // '\t'
							case 0x20: // ' '
							case 0x3A: // ':'
							case 0x3D: // '='
								lexemType = DELIMITER;

								if (!get(in, c))
								{
									finished = true;
								}

								break;

							case 0x0A:
							case 0x0D:
								// key associated with an empty string element
								properties.setProperty(key, LogString());
								key.erase(key.begin(), key.end());
								lexemType = BEGIN;

								if (!get(in, c))
								{
									finished = true;
								}

								break;

							default:
								key.append(1, c);

								if (!get(in, c))
								{
									finished = true;
								}

								break;
						}

						break;

					case KEY_ESCAPE:
						switch (c)
						{
							case 0x74: // 't'
								key.append(1, 0x09);
								lexemType = KEY;
								break;

							case 0x6E: // 'n'
								key.append(1, 0x0A);
								lexemType = KEY;
								break;

							case 0x72: // 'r'
								key.append(1, 0x0D);
								lexemType = KEY;
								break;

							case 0x0A: // '\n'
								lexemType = KEY_CONTINUE;
								break;

							case 0x0D: // '\r'
								lexemType = KEY_CONTINUE2;
								break;

							default:
								key.append(1, c);
								lexemType = KEY;
						}

						if (!get(in, c))
						{
							finished = true;
						}

						break;

					case KEY_CONTINUE:
						switch (c)
						{
							case 0x20:  // ' '
							case 0x09: //  '\t'
								if (!get(in, c))
								{
									finished = true;
								}

								break;

							default:
								lexemType = KEY;
								break;
						}

						break;

					case KEY_CONTINUE2:
						switch (c)
						{
							case 0x0A: // '\n'
								if (!get(in, c))
								{
									finished = true;
								}

								lexemType = KEY_CONTINUE;
								break;

							default:
								lexemType = KEY_CONTINUE;
								break;
						}

						break;

					case DELIMITER:
						switch (c)
						{
							case 0x09: // '\t'
							case 0x20: // ' '
							case 0x3A: // ':'
							case 0x3D: // '='
								if (!get(in, c))
								{
									finished = true;
								}

								break;

							default:
								lexemType = ELEMENT;
								break;
						}

						break;

					case ELEMENT:
						switch (c)
						{
							case 0x5C: // '\\'
								lexemType = ELEMENT_ESCAPE;

								if (!get(in, c))
								{
									finished = true;
								}

								break;

							case 0x0A: // '\n'
							case 0x0D: // '\r'
								// key associated with an empty string element
								properties.setProperty(key, element);
								key.erase(key.begin(), key.end());
								element.erase(element.begin(), element.end());
								lexemType = BEGIN;

								if (!get(in, c))
								{
									finished = true;
								}

								break;

							default:
								element.append(1, c);

								if (!get(in, c))
								{
									finished = true;
								}

								break;
						}

						break;

					case ELEMENT_ESCAPE:
						switch (c)
						{
							case 0x74: // 't'
								element.append(1, 0x09);
								lexemType = ELEMENT;
								break;

							case 0x6E: // 'n'
								element.append(1, 0x0A);
								lexemType = ELEMENT;
								break;

							case 0x72: // 'r'
								element.append(1, 0x0D);
								lexemType = ELEMENT;
								break;

							case 0x0A: // '\n'
								lexemType = ELEMENT_CONTINUE;
								break;

							case 0x0D: // '\r'
								lexemType = ELEMENT_CONTINUE2;
								break;

							default:
								element.append(1, c);
								lexemType = ELEMENT;
								break;
						}

						if (!get(in, c))
						{
							finished = true;
						}

						break;

					case ELEMENT_CONTINUE:
						switch (c)
						{
							case 0x20: // ' '
							case 0x09: // '\t'
								if (!get(in, c))
								{
									finished = true;
								}

								break;

							default:
								lexemType = ELEMENT;
								break;
						}

						break;

					case ELEMENT_CONTINUE2:
						switch (c)
						{
							case 0x0A: // '\n'
								if (!get(in, c))
								{
									finished = true;
								}

								lexemType = ELEMENT_CONTINUE;
								break;

							default:
								lexemType = ELEMENT_CONTINUE;
								break;
						}

						break;

					case COMMENT:
						if (c == 0x0A || c == 0x0D)
						{
							lexemType = BEGIN;
						}

						if (!get(in, c))
						{
							finished = true;
						}

						break;
				}
			}

			if (!key.empty())
			{
				properties.setProperty(key, element);
			}
		}

	protected:
		static bool get(LogString& in, logchar& c)
		{
			if (in.empty())
			{
				c = 0;
				return false;
			}

			c = in[0];
			in.erase(in.begin());
			return true;
		}

		typedef enum
		{
			BEGIN,
			KEY,
			KEY_ESCAPE,
			KEY_CONTINUE,
			KEY_CONTINUE2,
			DELIMITER,
			ELEMENT,
			ELEMENT_ESCAPE,
			ELEMENT_CONTINUE,
			ELEMENT_CONTINUE2,
			COMMENT
		}
		LexemType;
};

Properties::Properties() : properties(new PropertyMap())
{
}

Properties::~Properties()
{
	delete properties;
}

LogString Properties::setProperty(const LogString& key, const LogString& value)
{
	return put(key, value);
}

LogString Properties::put(const LogString& key, const LogString& value)
{
	LogString oldValue((*properties)[key]);
	(*properties)[key] = value;
	return oldValue;
}

LogString Properties::getProperty(const LogString& key) const
{
	return get(key);
}

LogString Properties::get(const LogString& key) const
{
	PropertyMap::const_iterator it = properties->find(key);
	return (it != properties->end()) ? it->second : LogString();
}

void Properties::load(InputStreamPtr inStream)
{
	Pool pool;
	InputStreamReaderPtr lineReader(
		new InputStreamReader(inStream, CharsetDecoder::getISOLatinDecoder()));
	LogString contents = lineReader->read(pool);
	properties->clear();
	PropertyParser parser;
	parser.parse(contents, *this);
}

std::vector<LogString> Properties::propertyNames() const
{
	std::vector<LogString> names;
	names.reserve(properties->size());

	PropertyMap::const_iterator it;

	for (it = properties->begin(); it != properties->end(); it++)
	{
		const LogString& key = it->first;
		names.push_back(key);
	}

	return names;
}

