/*
 * 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 <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 {
        IGNORE_GCC_WARNINGS_BEGIN("stringop-truncation")
        strncpy(m_filename, filename, s_maxPathLength);
        IGNORE_GCC_WARNINGS_END
        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.appendCharacters(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.appendCharacters(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()) {
            JSC::Config::enableRestrictedOptions();
            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
                IGNORE_GCC_WARNINGS_BEGIN("stringop-truncation")
                strncat(filenameBuffer, m_filename, sizeof(filenameBuffer) - strlen(filenameBuffer) - 1);
                IGNORE_GCC_WARNINGS_END
                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
