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

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

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

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

    auto newProvider = StringSourceProvider::create(newProviderStr, "<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.typeProfilingStartOffset, info.typeProfilingEndOffset + 1, 1, 1);
}
    
bool FunctionOverrides::initializeOverrideFor(const SourceCode& origCode, FunctionOverrides::OverrideInfo& result)
{
    ASSERT(Options::functionOverrides());
    FunctionOverrides& overrides = FunctionOverrides::overrides();

    auto it = overrides.m_entries.find(origCode.view().toString());
    if (it == overrides.m_entries.end())
        return false;

    initializeOverrideInfo(origCode, it->value, result);
    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)
{
    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);

    const char* terminator = terminatorString.ascii().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.append(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)
{
    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

