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

