/*
 * 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;
    Locker locker { m_lock };
    parseOverridesInFile(overridesFileName);
}

void FunctionOverrides::reinstallOverrides()
{
    FunctionOverridesAssertScope assertScope;
    FunctionOverrides& overrides = FunctionOverrides::overrides();
    Locker locker { overrides.m_lock };
    const char* overridesFileName = Options::functionOverrides();
    overrides.clear();
    overrides.parseOverridesInFile(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);

    auto overridden = "<overridden>"_s;
    URL url({ }, overridden);
    Ref<SourceProvider> newProvider = StringSourceProvider::create(newProviderStr, SourceOrigin { 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;
    {
        Locker locker { 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 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

