/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ConfigFile.h"

#include "Options.h"
#include <limits.h>
#include <mutex>
#include <stdio.h>
#include <string.h>
#include <wtf/ASCIICType.h>
#include <wtf/DataLog.h>
#include <wtf/text/StringBuilder.h>

#if HAVE(REGEX_H)
#include <regex.h>
#endif

#if OS(UNIX)
#include <unistd.h>
#endif

namespace JSC {

static const size_t s_processNameMax = 128;
char ConfigFile::s_processName[s_processNameMax + 1] = { 0 };
char ConfigFile::s_parentProcessName[s_processNameMax + 1] = { 0 };

class ConfigFileScanner {
public:
    ConfigFileScanner(const char* filename)
        : m_filename(filename)
        , m_lineNumber(0)
    {
        m_srcPtr = &m_buffer[0];
        m_bufferEnd = &m_buffer[0];
    }

    bool start()
    {
        m_file = fopen(m_filename, "r");
        if (!m_file) {
            dataLogF("Failed to open file JSC Config file '%s'.\n", m_filename);
            return false;
        }

        return true;
    }

    unsigned lineNumber()
    {
        return m_lineNumber;
    }

    const char* currentBuffer()
    {
        if (!m_srcPtr || m_srcPtr == m_bufferEnd)
            return "";

        return m_srcPtr;
    }

    bool atFileEnd()
    {
        if (!fillBufferIfNeeded())
            return true;

        return false;
    }

    bool tryConsume(char c)
    {
        if (!fillBufferIfNeeded())
            return false;

        if (c == *m_srcPtr) {
            m_srcPtr++;
            return true;
        }

        return false;
    }

    template <size_t length>
    bool tryConsume(const char (&token) [length])
    {
        if (!fillBufferIfNeeded())
            return false;

        size_t tokenLength = length - 1;
        if (!strncmp(m_srcPtr, token, tokenLength)) {
            m_srcPtr += tokenLength;
            return true;
        }

        return false;
    }

    char* tryConsumeString()
    {
        if (!fillBufferIfNeeded())
            return nullptr;

        if (*m_srcPtr != '"')
            return nullptr;

        char* stringStart = ++m_srcPtr;

        char* stringEnd = strchr(m_srcPtr, '"');
        if (stringEnd) {
            *stringEnd = '\0';
            m_srcPtr = stringEnd + 1;
            return stringStart;
        }

        return nullptr;
    }

    char* tryConsumeRegExPattern(bool& ignoreCase)
    {
        if (!fillBufferIfNeeded())
            return nullptr;

        if (*m_srcPtr != '/')
            return nullptr;

        char* stringStart = m_srcPtr + 1;

        char* stringEnd = strchr(stringStart, '/');
        if (stringEnd) {
            *stringEnd = '\0';
            m_srcPtr = stringEnd + 1;
            if (*m_srcPtr == 'i') {
                ignoreCase = true;
                m_srcPtr++;
            } else
                ignoreCase = false;

            return stringStart;
        }

        return nullptr;
    }
    
    char* tryConsumeUpto(bool& foundChar, char c)
    {
        if (!fillBufferIfNeeded())
            return nullptr;

        char* start = m_srcPtr;
        foundChar = false;

        char* cPosition = strchr(m_srcPtr, c);
        if (cPosition) {
            *cPosition = '\0';
            m_srcPtr = cPosition + 1;
            foundChar = true;
        } else
            m_srcPtr = m_bufferEnd;

        return start;
    }

private:
    bool fillBufferIfNeeded()
    {
        if (!m_srcPtr)
            return false;

        while (true) {
            while (m_srcPtr != m_bufferEnd && isASCIISpace(*m_srcPtr))
                m_srcPtr++;

            if (m_srcPtr != m_bufferEnd)
                break;

            if (!fillBuffer())
                return false;
        }

        return true;
    }

    bool fillBuffer()
    {
        do {
            m_srcPtr = fgets(m_buffer, sizeof(m_buffer), m_file);
            if (!m_srcPtr) {
                fclose(m_file);
                return false;
            }

            m_lineNumber++;

            m_bufferEnd = strchr(m_srcPtr, '#');

            if (m_bufferEnd)
                *m_bufferEnd = '\0';
            else {
                m_bufferEnd = m_srcPtr + strlen(m_srcPtr);
                if (m_bufferEnd > m_srcPtr && m_bufferEnd[-1] == '\n') {
                    m_bufferEnd--;
                    *m_bufferEnd = '\0';
                }
            }
        } while (m_bufferEnd == m_srcPtr);

        return true;
    }

    const char* m_filename;
    unsigned m_lineNumber;
    FILE* m_file;
    char m_buffer[BUFSIZ];
    char* m_srcPtr;
    char* m_bufferEnd;
};

ConfigFile::ConfigFile(const char* filename)
{
    if (!filename)
        m_filename[0] = '\0';
    else {
        strncpy(m_filename, filename, s_maxPathLength);
        m_filename[s_maxPathLength] = '\0';
    }

    m_configDirectory[0] = '\0';
}

void ConfigFile::setProcessName(const char* processName)
{
    strncpy(s_processName, processName, s_processNameMax);
}

void ConfigFile::setParentProcessName(const char* parentProcessName)
{
    strncpy(s_parentProcessName, parentProcessName, s_processNameMax);
}

void ConfigFile::parse()
{
    enum StatementNesting { TopLevelStatment, NestedStatement, NestedStatementFailedCriteria };
    enum ParseResult { ParseOK, ParseError, NestedStatementDone };

    canonicalizePaths();

    ConfigFileScanner scanner(m_filename);

    if (!scanner.start())
        return;

    char logPathname[s_maxPathLength + 1] = { 0 };

    StringBuilder jscOptionsBuilder;

    auto parseLogFile = [&](StatementNesting statementNesting) {
        char* filename = nullptr;
        if (scanner.tryConsume('=') && (filename = scanner.tryConsumeString())) {
            if (statementNesting != NestedStatementFailedCriteria) {
                if (filename[0] != '/') {
                    int spaceRequired = snprintf(logPathname, s_maxPathLength + 1, "%s/%s", m_configDirectory, filename);
                    if (static_cast<unsigned>(spaceRequired) > s_maxPathLength)
                        return ParseError;
                } else
                    strncpy(logPathname, filename, s_maxPathLength);
            }

            return ParseOK;
        }

        return ParseError;
    };

    auto parseJSCOptions = [&](StatementNesting statementNesting) {
        if (scanner.tryConsume('{')) {
            StringBuilder builder;

            bool foundClosingBrace = false;
            char* currentLine = nullptr;

            while ((currentLine = scanner.tryConsumeUpto(foundClosingBrace, '}'))) {
                char* p = currentLine;

                do {
                    if (foundClosingBrace && !*p)
                        break;

                    char* optionNameStart = p;

                    while (*p && !isASCIISpace(*p) && *p != '=')
                        p++;

                    builder.append(optionNameStart, p - optionNameStart);

                    while (*p && isASCIISpace(*p) && *p != '=')
                        p++;

                    if (!*p)
                        return ParseError;
                    p++; // Advance past the '='

                    builder.append('=');

                    while (*p && isASCIISpace(*p))
                        p++;

                    if (!*p)
                        return ParseError;

                    char* optionValueStart = p;

                    while (*p && !isASCIISpace(*p))
                        p++;

                    builder.append(optionValueStart, p - optionValueStart);
                    builder.append('\n');

                    while (*p && isASCIISpace(*p))
                        p++;
                } while (*p);

                if (foundClosingBrace)
                    break;
            }

            if (statementNesting != NestedStatementFailedCriteria)
                jscOptionsBuilder.append(builder);

            return ParseOK;
        }

        return ParseError;
    };

    auto parseNestedStatement = [&](StatementNesting statementNesting) {
        if (scanner.tryConsume("jscOptions"))
            return parseJSCOptions(statementNesting);

        if (scanner.tryConsume("logFile"))
            return parseLogFile(statementNesting);

        if (scanner.tryConsume('}'))
            return NestedStatementDone;

        return ParseError;
    };

    auto parsePredicate = [&](bool& predicateMatches, const char* matchValue) {
        if (scanner.tryConsume("==")) {
            char* predicateValue = nullptr;
            if ((predicateValue = scanner.tryConsumeString()) && matchValue) {
                predicateMatches = !strcmp(predicateValue, matchValue);
                return true;
            }
        }
#if HAVE(REGEX_H)
        else if (scanner.tryConsume("=~")) {
            char* predicateRegExString = nullptr;
            bool ignoreCase { false };
            if ((predicateRegExString = scanner.tryConsumeRegExPattern(ignoreCase)) && matchValue) {
                regex_t predicateRegEx;
                int regexFlags = REG_EXTENDED;
                if (ignoreCase)
                    regexFlags |= REG_ICASE;
                if (regcomp(&predicateRegEx, predicateRegExString, regexFlags))
                    return false;

                predicateMatches = !regexec(&predicateRegEx, matchValue, 0, nullptr, 0);
                return true;
            }
        }
#endif

        return false;
    };

    auto parseConditionalBlock = [&](StatementNesting statementNesting) {
        if (statementNesting == NestedStatement) {
            StatementNesting subNesting = NestedStatement;

            while (true) {
                bool predicateMatches;
                const char* actualValue = nullptr;

                if (scanner.tryConsume("processName"))
                    actualValue = s_processName;
                else if (scanner.tryConsume("parentProcessName"))
                    actualValue = s_parentProcessName;
                else if (scanner.tryConsume("build"))
#ifndef NDEBUG
                    actualValue = "Debug";
#else
                    actualValue = "Release";
#endif
                else
                    return ParseError;

                if (parsePredicate(predicateMatches, actualValue)) {
                    if (!predicateMatches)
                        subNesting = NestedStatementFailedCriteria;

                    if (!scanner.tryConsume("&&"))
                        break;
                }
            }

            if (!scanner.tryConsume('{'))
                return ParseError;

            ParseResult parseResult = ParseOK;
            while (parseResult == ParseOK && !scanner.atFileEnd())
                parseResult = parseNestedStatement(subNesting);

            if (parseResult == NestedStatementDone)
                return ParseOK;
        }

        return ParseError;
    };

    auto parseStatement = [&](StatementNesting statementNesting) {
        if (scanner.tryConsume("jscOptions"))
            return parseJSCOptions(statementNesting);

        if (scanner.tryConsume("logFile"))
            return parseLogFile(statementNesting);

        if (statementNesting == TopLevelStatment)
            return parseConditionalBlock(NestedStatement);

        return ParseError;
    };

    ParseResult parseResult = ParseOK;

    while (parseResult == ParseOK && !scanner.atFileEnd())
        parseResult = parseStatement(TopLevelStatment);

    if (parseResult == ParseOK) {
        if (strlen(logPathname))
            WTF::setDataFile(logPathname);

        if (!jscOptionsBuilder.isEmpty()) {
            Options::enableRestrictedOptions(true);
            Options::setOptions(jscOptionsBuilder.toString().utf8().data());
        }
    } else
        WTF::dataLogF("Error in JSC Config file on or near line %u, parsing '%s'\n", scanner.lineNumber(), scanner.currentBuffer());
}

void ConfigFile::canonicalizePaths()
{
    if (!m_filename[0])
        return;

#if OS(UNIX) || OS(DARWIN)
    if (m_filename[0] != '/') {
        // Relative path
        char filenameBuffer[s_maxPathLength + 1];

        if (getcwd(filenameBuffer, sizeof(filenameBuffer))) {
            size_t pathnameLength = strlen(filenameBuffer);
            bool shouldAddPathSeparator = filenameBuffer[pathnameLength - 1] != '/';
            if (sizeof(filenameBuffer) - 1  >= pathnameLength + shouldAddPathSeparator) {
                if (shouldAddPathSeparator)
                    strncat(filenameBuffer, "/", 2); // Room for '/' plus NUL
#if COMPILER(GCC)
#if GCC_VERSION_AT_LEAST(8, 0, 0)
                IGNORE_WARNINGS_BEGIN("stringop-truncation")
#endif
#endif
                strncat(filenameBuffer, m_filename, sizeof(filenameBuffer) - strlen(filenameBuffer) - 1);
#if COMPILER(GCC)
#if GCC_VERSION_AT_LEAST(8, 0, 0)
                IGNORE_WARNINGS_END
#endif
#endif
                strncpy(m_filename, filenameBuffer, s_maxPathLength);
                m_filename[s_maxPathLength] = '\0';
            }
        }
    }
#endif

    char* lastPathSeperator = strrchr(m_filename, '/');

    if (lastPathSeperator) {
        unsigned dirnameLength = lastPathSeperator - &m_filename[0];
        strncpy(m_configDirectory, m_filename, dirnameLength);
        m_configDirectory[dirnameLength] = '\0';
    } else {
        m_configDirectory[0] = '/';
        m_configDirectory[1] = '\0';
    }
}

void processConfigFile(const char* configFilename, const char* processName, const char* parentProcessName)
{
    static std::once_flag processConfigFileOnceFlag;
    
    if (!configFilename || !strlen(configFilename))
        return;

    std::call_once(processConfigFileOnceFlag, [&]{
        if (configFilename) {
            ConfigFile configFile(configFilename);
            configFile.setProcessName(processName);
            if (parentProcessName)
                configFile.setParentProcessName(parentProcessName);
            configFile.parse();
        }
    });
}

} // namespace JSC
