/*
 * Copyright (C) 2015-2019 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 "FunctionOverrides.h"

#include "Options.h"
#include <stdio.h>
#include <string.h>
#include <wtf/DataLog.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringHash.h>

namespace JSC {

/*
  The overrides file defines function bodies that we will want to override with
  a replacement for debugging purposes. The overrides file may contain
  'override' and 'with' clauses like these:

     // Example 1: function foo1(a)
     override !@#$%{ print("In foo1"); }!@#$%
     with abc{
         print("I am overridden");
     }abc

     // Example 2: function foo2(a)
     override %%%{
         print("foo2's body has a string with }%% in it.");
         // Because }%% appears in the function body here, we cannot use
         // %% or % as the delimiter. %%% is ok though.
     }%%%
     with %%%{
         print("Overridden foo2");
     }%%%

  1. Comments are lines starting with //.  All comments will be ignored.

  2. An 'override' clause is used to specify the original function body we
     want to override. The with clause is used to specify the overriding
     function body.

     An 'override' clause must be followed immediately by a 'with' clause.

  3. An 'override' clause must be of the form:
         override <delimiter>{...function body...}<delimiter>

     The override keyword must be at the start of the line.

     <delimiter> may be any string of any ASCII characters (except for '{',
     '}', and whitespace characters) as long as the pattern of "}<delimiter>"
     does not appear in the function body e.g. the override clause of Example 2
     above illustrates this.

     The start and end <delimiter> must be identical.

     The space between the override keyword and the start <delimiter> is
     required.

     All characters between the pair of delimiters will be considered to
     be part of the function body string. This allows us to also work
     with script source that are multi-lined i.e. newlines are allowed.
     
  4. A 'with' clause is identical in form to an 'override' clause except that
     it uses the 'with' keyword instead of the 'override' keyword.
 */

struct FunctionOverridesAssertScope {
    FunctionOverridesAssertScope() { RELEASE_ASSERT(g_jscConfig.restrictedOptionsEnabled); }
    ~FunctionOverridesAssertScope() { RELEASE_ASSERT(g_jscConfig.restrictedOptionsEnabled); }
};

FunctionOverrides& FunctionOverrides::overrides()
{
    FunctionOverridesAssertScope assertScope;
    static LazyNeverDestroyed<FunctionOverrides> overrides;
    static std::once_flag initializeListFlag;
    std::call_once(initializeListFlag, [] {
        FunctionOverridesAssertScope assertScope;
        const char* overridesFileName = Options::functionOverrides();
        overrides.construct(overridesFileName);
    });
    return overrides;
}
    
FunctionOverrides::FunctionOverrides(const char* overridesFileName)
{
    FunctionOverridesAssertScope assertScope;
    parseOverridesInFile(holdLock(m_lock), overridesFileName);
}

void FunctionOverrides::reinstallOverrides()
{
    FunctionOverridesAssertScope assertScope;
    FunctionOverrides& overrides = FunctionOverrides::overrides();
    auto locker = holdLock(overrides.m_lock);
    const char* overridesFileName = Options::functionOverrides();
    overrides.clear(locker);
    overrides.parseOverridesInFile(locker, overridesFileName);
}

static void initializeOverrideInfo(const SourceCode& origCode, const String& newBody, FunctionOverrides::OverrideInfo& info)
{
    FunctionOverridesAssertScope assertScope;
    String origProviderStr = origCode.provider()->source().toString();
    unsigned origStart = origCode.startOffset();
    unsigned origFunctionStart = origProviderStr.reverseFind("function", origStart);
    unsigned origBraceStart = origProviderStr.find("{", origStart);
    unsigned headerLength = origBraceStart - origFunctionStart;
    String origHeader = origProviderStr.substring(origFunctionStart, headerLength);

    String newProviderStr;
    newProviderStr.append(origHeader);
    newProviderStr.append(newBody);

    Ref<SourceProvider> newProvider = StringSourceProvider::create(newProviderStr, SourceOrigin { "<overridden>" }, URL({ }, "<overridden>"));

    info.firstLine = 1;
    info.lineCount = 1; // Faking it. This doesn't really matter for now.
    info.startColumn = 1;
    info.endColumn = 1; // Faking it. This doesn't really matter for now.
    info.parametersStartOffset = newProviderStr.find("(");
    info.typeProfilingStartOffset = newProviderStr.find("{");
    info.typeProfilingEndOffset = newProviderStr.length() - 1;

    info.sourceCode =
        SourceCode(WTFMove(newProvider), info.parametersStartOffset, info.typeProfilingEndOffset + 1, 1, 1);
}
    
bool FunctionOverrides::initializeOverrideFor(const SourceCode& origCode, FunctionOverrides::OverrideInfo& result)
{
    FunctionOverridesAssertScope assertScope;
    RELEASE_ASSERT(Options::functionOverrides());
    FunctionOverrides& overrides = FunctionOverrides::overrides();

    String sourceString = origCode.view().toString();
    size_t sourceBodyStart = sourceString.find('{');
    if (sourceBodyStart == notFound)
        return false;
    String sourceBodyString = sourceString.substring(sourceBodyStart);

    String newBody;
    {
        auto locker = holdLock(overrides.m_lock);
        auto it = overrides.m_entries.find(sourceBodyString.isolatedCopy());
        if (it == overrides.m_entries.end())
            return false;
        newBody = it->value.isolatedCopy();
    }

    initializeOverrideInfo(origCode, newBody, result);
    RELEASE_ASSERT(Options::functionOverrides());
    return true;
}

#define SYNTAX_ERROR "SYNTAX ERROR"
#define IO_ERROR "IO ERROR"
#define FAIL_WITH_ERROR(error, errorMessageInBrackets) \
    do { \
        dataLog("functionOverrides ", error, ": "); \
        dataLog errorMessageInBrackets; \
        exit(EXIT_FAILURE); \
    } while (false)

static bool hasDisallowedCharacters(const char* str, size_t length)
{
    while (length--) {
        char c = *str++;
        // '{' is also disallowed, but we don't need to check for it because
        // parseClause() searches for '{' as the end of the start delimiter.
        // As a result, the parsed delimiter string will never include '{'.
        if (c == '}' || isASCIISpace(c))
            return true;
    }
    return false;
}

static String parseClause(const char* keyword, size_t keywordLength, FILE* file, const char* line, char* buffer, size_t bufferSize)
{
    FunctionOverridesAssertScope assertScope;
    const char* keywordPos = strstr(line, keyword);
    if (!keywordPos)
        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Expecting '", keyword, "' clause:\n", line, "\n"));
    if (keywordPos != line)
        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Cannot have any characters before '", keyword, "':\n", line, "\n"));
    if (line[keywordLength] != ' ')
        FAIL_WITH_ERROR(SYNTAX_ERROR, ("'", keyword, "' must be followed by a ' ':\n", line, "\n"));

    const char* delimiterStart = &line[keywordLength + 1];
    const char* delimiterEnd = strstr(delimiterStart, "{");
    if (!delimiterEnd)
        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Missing { after '", keyword, "' clause start delimiter:\n", line, "\n"));
    
    size_t delimiterLength = delimiterEnd - delimiterStart;
    String delimiter(delimiterStart, delimiterLength);

    if (hasDisallowedCharacters(delimiterStart, delimiterLength))
        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Delimiter '", delimiter, "' cannot have '{', '}', or whitespace:\n", line, "\n"));
    
    String terminatorString;
    terminatorString.append('}');
    terminatorString.append(delimiter);

    CString terminatorCString = terminatorString.ascii();
    const char* terminator = terminatorCString.data();
    line = delimiterEnd; // Start from the {.

    StringBuilder builder;
    do {
        const char* p = strstr(line, terminator);
        if (p) {
            if (p[strlen(terminator)] != '\n')
                FAIL_WITH_ERROR(SYNTAX_ERROR, ("Unexpected characters after '", keyword, "' clause end delimiter '", delimiter, "':\n", line, "\n"));

            builder.appendCharacters(line, p - line + 1);
            return builder.toString();
        }
        builder.append(line);

    } while ((line = fgets(buffer, bufferSize, file)));

    FAIL_WITH_ERROR(SYNTAX_ERROR, ("'", keyword, "' clause end delimiter '", delimiter, "' not found:\n", builder.toString(), "\n", "Are you missing a '}' before the delimiter?\n"));
}

void FunctionOverrides::parseOverridesInFile(const AbstractLocker&, const char* fileName)
{
    FunctionOverridesAssertScope assertScope;
    if (!fileName)
        return;
    
    FILE* file = fopen(fileName, "r");
    if (!file)
        FAIL_WITH_ERROR(IO_ERROR, ("Failed to open file ", fileName, ". Did you add the file-read-data entitlement to WebProcess.sb?\n"));

    char* line;
    char buffer[BUFSIZ];
    while ((line = fgets(buffer, sizeof(buffer), file))) {
        if (strstr(line, "//") == line)
            continue;

        if (line[0] == '\n' || line[0] == '\0')
            continue;

        size_t keywordLength;
        
        keywordLength = sizeof("override") - 1;
        String keyStr = parseClause("override", keywordLength, file, line, buffer, sizeof(buffer));

        line = fgets(buffer, sizeof(buffer), file);

        keywordLength = sizeof("with") - 1;
        String valueStr = parseClause("with", keywordLength, file, line, buffer, sizeof(buffer));

        m_entries.add(keyStr, valueStr);
    }
    
    int result = fclose(file);
    if (result)
        dataLogF("Failed to close file %s: %s\n", fileName, strerror(errno));
}
    
} // namespace JSC

