/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iomanip>
#include <iostream>
#include <cmath>
#include <sstream>

#include "Generator.h"
#include "Specification.h"
#include "Utilities.h"

using namespace std;

// Converts float2 to FLOAT_32 and 2, etc.
static void convertToRsType(const string& name, string* dataType, char* vectorSize) {
    string s = name;
    int last = s.size() - 1;
    char lastChar = s[last];
    if (lastChar >= '1' && lastChar <= '4') {
        s.erase(last);
        *vectorSize = lastChar;
    } else {
        *vectorSize = '1';
    }
    dataType->clear();
    for (int i = 0; i < NUM_TYPES; i++) {
        if (s == TYPES[i].cType) {
            *dataType = TYPES[i].rsDataType;
            break;
        }
    }
}

// Returns true if any permutation of the function have tests to b
static bool needTestFiles(const Function& function, unsigned int versionOfTestFiles) {
    for (auto spec : function.getSpecifications()) {
        if (spec->hasTests(versionOfTestFiles)) {
            return true;
        }
    }
    return false;
}

/* One instance of this class is generated for each permutation of a function for which
 * we are generating test code.  This instance will generate both the script and the Java
 * section of the test files for this permutation.  The class is mostly used to keep track
 * of the various names shared between script and Java files.
 * WARNING: Because the constructor keeps a reference to the FunctionPermutation, PermutationWriter
 * should not exceed the lifetime of FunctionPermutation.
 */
class PermutationWriter {
private:
    FunctionPermutation& mPermutation;

    string mRsKernelName;
    string mJavaArgumentsClassName;
    string mJavaArgumentsNClassName;
    string mJavaVerifierComputeMethodName;
    string mJavaVerifierVerifyMethodName;
    string mJavaCheckMethodName;
    string mJavaVerifyMethodName;

    // Pointer to the files we are generating.  Handy to avoid always passing them in the calls.
    GeneratedFile* mRs;
    GeneratedFile* mJava;

    /* Shortcuts to the return parameter and the first input parameter of the function
     * specification.
     */
    const ParameterDefinition* mReturnParam;      // Can be nullptr.  NOT OWNED.
    const ParameterDefinition* mFirstInputParam;  // Can be nullptr.  NOT OWNED.

    /* All the parameters plus the return param, if present.  Collecting them together
     * simplifies code generation.  NOT OWNED.
     */
    vector<const ParameterDefinition*> mAllInputsAndOutputs;

    /* We use a class to pass the arguments between the generated code and the CoreVerifier.  This
     * method generates this class.  The set keeps track if we've generated this class already
     * for this test file, as more than one permutation may use the same argument class.
     */
    void writeJavaArgumentClass(bool scalar, set<string>* javaGeneratedArgumentClasses) const;

    // Generate the Check* method that invokes the script and calls the verifier.
    void writeJavaCheckMethod(bool generateCallToVerifier) const;

    // Generate code to define and randomly initialize the input allocation.
    void writeJavaInputAllocationDefinition(const ParameterDefinition& param) const;

    /* Generate code that instantiate an allocation of floats or integers and fills it with
     * random data. This random data must be compatible with the specified type.  This is
     * used for the convert_* tests, as converting values that don't fit yield undefined results.
     */
    void writeJavaRandomCompatibleFloatAllocation(const string& dataType, const string& seed,
                                                  char vectorSize,
                                                  const NumericalType& compatibleType,
                                                  const NumericalType& generatedType) const;
    void writeJavaRandomCompatibleIntegerAllocation(const string& dataType, const string& seed,
                                                    char vectorSize,
                                                    const NumericalType& compatibleType,
                                                    const NumericalType& generatedType) const;

    // Generate code that defines an output allocation.
    void writeJavaOutputAllocationDefinition(const ParameterDefinition& param) const;

    /* Generate the code that verifies the results for RenderScript functions where each entry
     * of a vector is evaluated independently.  If verifierValidates is true, CoreMathVerifier
     * does the actual validation instead of more commonly returning the range of acceptable values.
     */
    void writeJavaVerifyScalarMethod(bool verifierValidates) const;

    /* Generate the code that verify the results for a RenderScript function where a vector
     * is a point in n-dimensional space.
     */
    void writeJavaVerifyVectorMethod() const;

    // Generate the line that creates the Target.
    void writeJavaCreateTarget() const;

    // Generate the method header of the verify function.
    void writeJavaVerifyMethodHeader() const;

    // Generate codes that copies the content of an allocation to an array.
    void writeJavaArrayInitialization(const ParameterDefinition& p) const;

    // Generate code that tests one value returned from the script.
    void writeJavaTestAndSetValid(const ParameterDefinition& p, const string& argsIndex,
                                  const string& actualIndex) const;
    void writeJavaTestOneValue(const ParameterDefinition& p, const string& argsIndex,
                               const string& actualIndex) const;
    // For test:vector cases, generate code that compares returned vector vs. expected value.
    void writeJavaVectorComparison(const ParameterDefinition& p) const;

    // Muliple functions that generates code to build the error message if an error is found.
    void writeJavaAppendOutputToMessage(const ParameterDefinition& p, const string& argsIndex,
                                        const string& actualIndex, bool verifierValidates) const;
    void writeJavaAppendInputToMessage(const ParameterDefinition& p, const string& actual) const;
    void writeJavaAppendNewLineToMessage() const;
    void writeJavaAppendVectorInputToMessage(const ParameterDefinition& p) const;
    void writeJavaAppendVectorOutputToMessage(const ParameterDefinition& p) const;

    // Generate the set of instructions to call the script.
    void writeJavaCallToRs(bool relaxed, bool generateCallToVerifier) const;

    // Write an allocation definition if not already emitted in the .rs file.
    void writeRsAllocationDefinition(const ParameterDefinition& param,
                                     set<string>* rsAllocationsGenerated) const;

public:
    /* NOTE: We keep pointers to the permutation and the files.  This object should not
     * outlive the arguments.
     */
    PermutationWriter(FunctionPermutation& permutation, GeneratedFile* rsFile,
                      GeneratedFile* javaFile);
    string getJavaCheckMethodName() const { return mJavaCheckMethodName; }

    // Write the script test function for this permutation.
    void writeRsSection(set<string>* rsAllocationsGenerated) const;
    // Write the section of the Java code that calls the script and validates the results
    void writeJavaSection(set<string>* javaGeneratedArgumentClasses) const;
};

PermutationWriter::PermutationWriter(FunctionPermutation& permutation, GeneratedFile* rsFile,
                                     GeneratedFile* javaFile)
    : mPermutation(permutation),
      mRs(rsFile),
      mJava(javaFile),
      mReturnParam(nullptr),
      mFirstInputParam(nullptr) {
    mRsKernelName = "test" + capitalize(permutation.getName());

    mJavaArgumentsClassName = "Arguments";
    mJavaArgumentsNClassName = "Arguments";
    const string trunk = capitalize(permutation.getNameTrunk());
    mJavaCheckMethodName = "check" + trunk;
    mJavaVerifyMethodName = "verifyResults" + trunk;

    for (auto p : permutation.getParams()) {
        mAllInputsAndOutputs.push_back(p);
        if (mFirstInputParam == nullptr && !p->isOutParameter) {
            mFirstInputParam = p;
        }
    }
    mReturnParam = permutation.getReturn();
    if (mReturnParam) {
        mAllInputsAndOutputs.push_back(mReturnParam);
    }

    for (auto p : mAllInputsAndOutputs) {
        const string capitalizedRsType = capitalize(p->rsType);
        const string capitalizedBaseType = capitalize(p->rsBaseType);
        mRsKernelName += capitalizedRsType;
        mJavaArgumentsClassName += capitalizedBaseType;
        mJavaArgumentsNClassName += capitalizedBaseType;
        if (p->mVectorSize != "1") {
            mJavaArgumentsNClassName += "N";
        }
        mJavaCheckMethodName += capitalizedRsType;
        mJavaVerifyMethodName += capitalizedRsType;
    }
    mJavaVerifierComputeMethodName = "compute" + trunk;
    mJavaVerifierVerifyMethodName = "verify" + trunk;
}

void PermutationWriter::writeJavaSection(set<string>* javaGeneratedArgumentClasses) const {
    // By default, we test the results using item by item comparison.
    const string test = mPermutation.getTest();
    if (test == "scalar" || test == "limited") {
        writeJavaArgumentClass(true, javaGeneratedArgumentClasses);
        writeJavaCheckMethod(true);
        writeJavaVerifyScalarMethod(false);
    } else if (test == "custom") {
        writeJavaArgumentClass(true, javaGeneratedArgumentClasses);
        writeJavaCheckMethod(true);
        writeJavaVerifyScalarMethod(true);
    } else if (test == "vector") {
        writeJavaArgumentClass(false, javaGeneratedArgumentClasses);
        writeJavaCheckMethod(true);
        writeJavaVerifyVectorMethod();
    } else if (test == "noverify") {
        writeJavaCheckMethod(false);
    }
}

void PermutationWriter::writeJavaArgumentClass(bool scalar,
                                               set<string>* javaGeneratedArgumentClasses) const {
    string name;
    if (scalar) {
        name = mJavaArgumentsClassName;
    } else {
        name = mJavaArgumentsNClassName;
    }

    // Make sure we have not generated the argument class already.
    if (!testAndSet(name, javaGeneratedArgumentClasses)) {
        mJava->indent() << "public class " << name;
        mJava->startBlock();

        for (auto p : mAllInputsAndOutputs) {
            bool isFieldArray = !scalar && p->mVectorSize != "1";
            bool isFloatyField = p->isOutParameter && p->isFloatType && mPermutation.getTest() != "custom";

            mJava->indent() << "public ";
            if (isFloatyField) {
                *mJava << "Target.Floaty";
            } else {
                *mJava << p->javaBaseType;
            }
            if (isFieldArray) {
                *mJava << "[]";
            }
            *mJava << " " << p->variableName << ";\n";

            // For Float16 parameters, add an extra 'double' field in the class
            // to hold the Double value converted from the input.
            if (p->isFloat16Parameter() && !isFloatyField) {
                mJava->indent() << "public double";
                if (isFieldArray) {
                    *mJava << "[]";
                }
                *mJava << " " + p->variableName << "Double;\n";
            }
        }
        mJava->endBlock();
        *mJava << "\n";
    }
}

void PermutationWriter::writeJavaCheckMethod(bool generateCallToVerifier) const {
    mJava->indent() << "private void " << mJavaCheckMethodName << "()";
    mJava->startBlock();

    // Generate the input allocations and initialization.
    for (auto p : mAllInputsAndOutputs) {
        if (!p->isOutParameter) {
            writeJavaInputAllocationDefinition(*p);
        }
    }
    // Generate code to enforce ordering between two allocations if needed.
    for (auto p : mAllInputsAndOutputs) {
        if (!p->isOutParameter && !p->smallerParameter.empty()) {
            string smallerAlloc = "in" + capitalize(p->smallerParameter);
            mJava->indent() << "enforceOrdering(" << smallerAlloc << ", " << p->javaAllocName
                            << ");\n";
        }
    }

    // Generate code to check the full and relaxed scripts.
    writeJavaCallToRs(false, generateCallToVerifier);
    writeJavaCallToRs(true, generateCallToVerifier);

    mJava->endBlock();
    *mJava << "\n";
}

void PermutationWriter::writeJavaInputAllocationDefinition(const ParameterDefinition& param) const {
    string dataType;
    char vectorSize;
    convertToRsType(param.rsType, &dataType, &vectorSize);

    const string seed = hashString(mJavaCheckMethodName + param.javaAllocName);
    mJava->indent() << "Allocation " << param.javaAllocName << " = ";
    if (param.compatibleTypeIndex >= 0) {
        if (TYPES[param.typeIndex].kind == FLOATING_POINT) {
            writeJavaRandomCompatibleFloatAllocation(dataType, seed, vectorSize,
                                                     TYPES[param.compatibleTypeIndex],
                                                     TYPES[param.typeIndex]);
        } else {
            writeJavaRandomCompatibleIntegerAllocation(dataType, seed, vectorSize,
                                                       TYPES[param.compatibleTypeIndex],
                                                       TYPES[param.typeIndex]);
        }
    } else if (!param.minValue.empty()) {
        *mJava << "createRandomFloatAllocation(mRS, Element.DataType." << dataType << ", "
               << vectorSize << ", " << seed << ", " << param.minValue << ", " << param.maxValue
               << ")";
    } else {
        /* TODO Instead of passing always false, check whether we are doing a limited test.
         * Use instead: (mPermutation.getTest() == "limited" ? "false" : "true")
         */
        *mJava << "createRandomAllocation(mRS, Element.DataType." << dataType << ", " << vectorSize
               << ", " << seed << ", false)";
    }
    *mJava << ";\n";
}

void PermutationWriter::writeJavaRandomCompatibleFloatAllocation(
            const string& dataType, const string& seed, char vectorSize,
            const NumericalType& compatibleType, const NumericalType& generatedType) const {
    *mJava << "createRandomFloatAllocation"
           << "(mRS, Element.DataType." << dataType << ", " << vectorSize << ", " << seed << ", ";
    double minValue = 0.0;
    double maxValue = 0.0;
    switch (compatibleType.kind) {
        case FLOATING_POINT: {
            // We're generating floating point values.  We just worry about the exponent.
            // Subtract 1 for the exponent sign.
            int bits = min(compatibleType.exponentBits, generatedType.exponentBits) - 1;
            maxValue = ldexp(0.95, (1 << bits) - 1);
            minValue = -maxValue;
            break;
        }
        case UNSIGNED_INTEGER:
            maxValue = maxDoubleForInteger(compatibleType.significantBits,
                                           generatedType.significantBits);
            minValue = 0.0;
            break;
        case SIGNED_INTEGER:
            maxValue = maxDoubleForInteger(compatibleType.significantBits,
                                           generatedType.significantBits);
            minValue = -maxValue - 1.0;
            break;
    }
    *mJava << scientific << std::setprecision(19);
    *mJava << minValue << ", " << maxValue << ")";
    mJava->unsetf(ios_base::floatfield);
}

void PermutationWriter::writeJavaRandomCompatibleIntegerAllocation(
            const string& dataType, const string& seed, char vectorSize,
            const NumericalType& compatibleType, const NumericalType& generatedType) const {
    *mJava << "createRandomIntegerAllocation"
           << "(mRS, Element.DataType." << dataType << ", " << vectorSize << ", " << seed << ", ";

    if (compatibleType.kind == FLOATING_POINT) {
        // Currently, all floating points can take any number we generate.
        bool isSigned = generatedType.kind == SIGNED_INTEGER;
        *mJava << (isSigned ? "true" : "false") << ", " << generatedType.significantBits;
    } else {
        bool isSigned =
                    compatibleType.kind == SIGNED_INTEGER && generatedType.kind == SIGNED_INTEGER;
        *mJava << (isSigned ? "true" : "false") << ", "
               << min(compatibleType.significantBits, generatedType.significantBits);
    }
    *mJava << ")";
}

void PermutationWriter::writeJavaOutputAllocationDefinition(
            const ParameterDefinition& param) const {
    string dataType;
    char vectorSize;
    convertToRsType(param.rsType, &dataType, &vectorSize);
    mJava->indent() << "Allocation " << param.javaAllocName << " = Allocation.createSized(mRS, "
                    << "getElement(mRS, Element.DataType." << dataType << ", " << vectorSize
                    << "), INPUTSIZE);\n";
}

void PermutationWriter::writeJavaVerifyScalarMethod(bool verifierValidates) const {
    writeJavaVerifyMethodHeader();
    mJava->startBlock();

    string vectorSize = "1";
    for (auto p : mAllInputsAndOutputs) {
        writeJavaArrayInitialization(*p);
        if (p->mVectorSize != "1" && p->mVectorSize != vectorSize) {
            if (vectorSize == "1") {
                vectorSize = p->mVectorSize;
            } else {
                cerr << "Error.  Had vector " << vectorSize << " and " << p->mVectorSize << "\n";
            }
        }
    }

    mJava->indent() << "StringBuilder message = new StringBuilder();\n";
    mJava->indent() << "boolean errorFound = false;\n";
    mJava->indent() << "for (int i = 0; i < INPUTSIZE; i++)";
    mJava->startBlock();

    mJava->indent() << "for (int j = 0; j < " << vectorSize << " ; j++)";
    mJava->startBlock();

    mJava->indent() << "// Extract the inputs.\n";
    mJava->indent() << mJavaArgumentsClassName << " args = new " << mJavaArgumentsClassName
                    << "();\n";
    for (auto p : mAllInputsAndOutputs) {
        if (!p->isOutParameter) {
            mJava->indent() << "args." << p->variableName << " = " << p->javaArrayName << "[i";
            if (p->vectorWidth != "1") {
                *mJava << " * " << p->vectorWidth << " + j";
            }
            *mJava << "];\n";

            // Convert the Float16 parameter to double and store it in the appropriate field in the
            // Arguments class.
            if (p->isFloat16Parameter()) {
                mJava->indent() << "args." << p->doubleVariableName
                                << " = Float16Utils.convertFloat16ToDouble(args."
                                << p->variableName << ");\n";
            }
        }
    }
    const bool hasFloat = mPermutation.hasFloatAnswers();
    if (verifierValidates) {
        mJava->indent() << "// Extract the outputs.\n";
        for (auto p : mAllInputsAndOutputs) {
            if (p->isOutParameter) {
                mJava->indent() << "args." << p->variableName << " = " << p->javaArrayName
                                << "[i * " << p->vectorWidth << " + j];\n";
                if (p->isFloat16Parameter()) {
                    mJava->indent() << "args." << p->doubleVariableName
                                    << " = Float16Utils.convertFloat16ToDouble(args."
                                    << p->variableName << ");\n";
                }
            }
        }
        mJava->indent() << "// Ask the CoreMathVerifier to validate.\n";
        if (hasFloat) {
            writeJavaCreateTarget();
        }
        mJava->indent() << "String errorMessage = CoreMathVerifier."
                        << mJavaVerifierVerifyMethodName << "(args";
        if (hasFloat) {
            *mJava << ", target";
        }
        *mJava << ");\n";
        mJava->indent() << "boolean valid = errorMessage == null;\n";
    } else {
        mJava->indent() << "// Figure out what the outputs should have been.\n";
        if (hasFloat) {
            writeJavaCreateTarget();
        }
        mJava->indent() << "CoreMathVerifier." << mJavaVerifierComputeMethodName << "(args";
        if (hasFloat) {
            *mJava << ", target";
        }
        *mJava << ");\n";
        mJava->indent() << "// Validate the outputs.\n";
        mJava->indent() << "boolean valid = true;\n";
        for (auto p : mAllInputsAndOutputs) {
            if (p->isOutParameter) {
                writeJavaTestAndSetValid(*p, "", "[i * " + p->vectorWidth + " + j]");
            }
        }
    }

    mJava->indent() << "if (!valid)";
    mJava->startBlock();
    mJava->indent() << "if (!errorFound)";
    mJava->startBlock();
    mJava->indent() << "errorFound = true;\n";

    for (auto p : mAllInputsAndOutputs) {
        if (p->isOutParameter) {
            writeJavaAppendOutputToMessage(*p, "", "[i * " + p->vectorWidth + " + j]",
                                           verifierValidates);
        } else {
            writeJavaAppendInputToMessage(*p, "args." + p->variableName);
        }
    }
    if (verifierValidates) {
        mJava->indent() << "message.append(errorMessage);\n";
    }
    mJava->indent() << "message.append(\"Errors at\");\n";
    mJava->endBlock();

    mJava->indent() << "message.append(\" [\");\n";
    mJava->indent() << "message.append(Integer.toString(i));\n";
    mJava->indent() << "message.append(\", \");\n";
    mJava->indent() << "message.append(Integer.toString(j));\n";
    mJava->indent() << "message.append(\"]\");\n";

    mJava->endBlock();
    mJava->endBlock();
    mJava->endBlock();

    mJava->indent() << "assertFalse(\"Incorrect output for " << mJavaCheckMethodName << "\" +\n";
    mJava->indentPlus()
                << "(relaxed ? \"_relaxed\" : \"\") + \":\\n\" + message.toString(), errorFound);\n";

    mJava->endBlock();
    *mJava << "\n";
}

void PermutationWriter::writeJavaVerifyVectorMethod() const {
    writeJavaVerifyMethodHeader();
    mJava->startBlock();

    for (auto p : mAllInputsAndOutputs) {
        writeJavaArrayInitialization(*p);
    }
    mJava->indent() << "StringBuilder message = new StringBuilder();\n";
    mJava->indent() << "boolean errorFound = false;\n";
    mJava->indent() << "for (int i = 0; i < INPUTSIZE; i++)";
    mJava->startBlock();

    mJava->indent() << mJavaArgumentsNClassName << " args = new " << mJavaArgumentsNClassName
                    << "();\n";

    mJava->indent() << "// Create the appropriate sized arrays in args\n";
    for (auto p : mAllInputsAndOutputs) {
        if (p->mVectorSize != "1") {
            string type = p->javaBaseType;
            if (p->isOutParameter && p->isFloatType) {
                type = "Target.Floaty";
            }
            mJava->indent() << "args." << p->variableName << " = new " << type << "["
                            << p->mVectorSize << "];\n";
            if (p->isFloat16Parameter() && !p->isOutParameter) {
                mJava->indent() << "args." << p->variableName << "Double = new double["
                                << p->mVectorSize << "];\n";
            }
        }
    }

    mJava->indent() << "// Fill args with the input values\n";
    for (auto p : mAllInputsAndOutputs) {
        if (!p->isOutParameter) {
            if (p->mVectorSize == "1") {
                mJava->indent() << "args." << p->variableName << " = " << p->javaArrayName << "[i]"
                                << ";\n";
                // Convert the Float16 parameter to double and store it in the appropriate field in
                // the Arguments class.
                if (p->isFloat16Parameter()) {
                    mJava->indent() << "args." << p->doubleVariableName << " = "
                                    << "Float16Utils.convertFloat16ToDouble(args."
                                    << p->variableName << ");\n";
                }
            } else {
                mJava->indent() << "for (int j = 0; j < " << p->mVectorSize << " ; j++)";
                mJava->startBlock();
                mJava->indent() << "args." << p->variableName << "[j] = "
                                << p->javaArrayName << "[i * " << p->vectorWidth << " + j]"
                                << ";\n";

                // Convert the Float16 parameter to double and store it in the appropriate field in
                // the Arguments class.
                if (p->isFloat16Parameter()) {
                    mJava->indent() << "args." << p->doubleVariableName << "[j] = "
                                    << "Float16Utils.convertFloat16ToDouble(args."
                                    << p->variableName << "[j]);\n";
                }
                mJava->endBlock();
            }
        }
    }
    writeJavaCreateTarget();
    mJava->indent() << "CoreMathVerifier." << mJavaVerifierComputeMethodName
                    << "(args, target);\n\n";

    mJava->indent() << "// Compare the expected outputs to the actual values returned by RS.\n";
    mJava->indent() << "boolean valid = true;\n";
    for (auto p : mAllInputsAndOutputs) {
        if (p->isOutParameter) {
            writeJavaVectorComparison(*p);
        }
    }

    mJava->indent() << "if (!valid)";
    mJava->startBlock();
    mJava->indent() << "if (!errorFound)";
    mJava->startBlock();
    mJava->indent() << "errorFound = true;\n";

    for (auto p : mAllInputsAndOutputs) {
        if (p->isOutParameter) {
            writeJavaAppendVectorOutputToMessage(*p);
        } else {
            writeJavaAppendVectorInputToMessage(*p);
        }
    }
    mJava->indent() << "message.append(\"Errors at\");\n";
    mJava->endBlock();

    mJava->indent() << "message.append(\" [\");\n";
    mJava->indent() << "message.append(Integer.toString(i));\n";
    mJava->indent() << "message.append(\"]\");\n";

    mJava->endBlock();
    mJava->endBlock();

    mJava->indent() << "assertFalse(\"Incorrect output for " << mJavaCheckMethodName << "\" +\n";
    mJava->indentPlus()
                << "(relaxed ? \"_relaxed\" : \"\") + \":\\n\" + message.toString(), errorFound);\n";

    mJava->endBlock();
    *mJava << "\n";
}


void PermutationWriter::writeJavaCreateTarget() const {
    string name = mPermutation.getName();

    const char* functionType = "NORMAL";
    size_t end = name.find('_');
    if (end != string::npos) {
        if (name.compare(0, end, "native") == 0) {
            functionType = "NATIVE";
        } else if (name.compare(0, end, "half") == 0) {
            functionType = "HALF";
        } else if (name.compare(0, end, "fast") == 0) {
            functionType = "FAST";
        }
    }

    string floatType = mReturnParam->specType;
    const char* precisionStr = "";
    if (floatType.compare("f16") == 0) {
        precisionStr = "HALF";
    } else if (floatType.compare("f32") == 0) {
        precisionStr = "FLOAT";
    } else if (floatType.compare("f64") == 0) {
        precisionStr = "DOUBLE";
    } else {
        cerr << "Error. Unreachable.  Return type is not floating point\n";
    }

    mJava->indent() << "Target target = new Target(Target.FunctionType." <<
                    functionType << ", Target.ReturnType." << precisionStr <<
                    ", relaxed);\n";
}

void PermutationWriter::writeJavaVerifyMethodHeader() const {
    mJava->indent() << "private void " << mJavaVerifyMethodName << "(";
    for (auto p : mAllInputsAndOutputs) {
        *mJava << "Allocation " << p->javaAllocName << ", ";
    }
    *mJava << "boolean relaxed)";
}

void PermutationWriter::writeJavaArrayInitialization(const ParameterDefinition& p) const {
    mJava->indent() << p.javaBaseType << "[] " << p.javaArrayName << " = new " << p.javaBaseType
                    << "[INPUTSIZE * " << p.vectorWidth << "];\n";

    /* For basic types, populate the array with values, to help understand failures.  We have had
     * bugs where the output buffer was all 0.  We were not sure if there was a failed copy or
     * the GPU driver was copying zeroes.
     */
    if (p.typeIndex >= 0) {
        mJava->indent() << "Arrays.fill(" << p.javaArrayName << ", (" << TYPES[p.typeIndex].javaType
                        << ") 42);\n";
    }

    mJava->indent() << p.javaAllocName << ".copyTo(" << p.javaArrayName << ");\n";
}

void PermutationWriter::writeJavaTestAndSetValid(const ParameterDefinition& p,
                                                 const string& argsIndex,
                                                 const string& actualIndex) const {
    writeJavaTestOneValue(p, argsIndex, actualIndex);
    mJava->startBlock();
    mJava->indent() << "valid = false;\n";
    mJava->endBlock();
}

void PermutationWriter::writeJavaTestOneValue(const ParameterDefinition& p, const string& argsIndex,
                                              const string& actualIndex) const {
    string actualOut;
    if (p.isFloat16Parameter()) {
        // For Float16 values, the output needs to be converted to Double.
        actualOut = "Float16Utils.convertFloat16ToDouble(" + p.javaArrayName + actualIndex + ")";
    } else {
        actualOut = p.javaArrayName + actualIndex;
    }

    mJava->indent() << "if (";
    if (p.isFloatType) {
        *mJava << "!args." << p.variableName << argsIndex << ".couldBe(" << actualOut;
        const string s = mPermutation.getPrecisionLimit();
        if (!s.empty()) {
            *mJava << ", " << s;
        }
        *mJava << ")";
    } else {
        *mJava << "args." << p.variableName << argsIndex << " != " << p.javaArrayName
               << actualIndex;
    }

    if (p.undefinedIfOutIsNan && mReturnParam) {
        *mJava << " && !args." << mReturnParam->variableName << argsIndex << ".isNaN()";
    }
    *mJava << ")";
}

void PermutationWriter::writeJavaVectorComparison(const ParameterDefinition& p) const {
    if (p.mVectorSize == "1") {
        writeJavaTestAndSetValid(p, "", "[i]");
    } else {
        mJava->indent() << "for (int j = 0; j < " << p.mVectorSize << " ; j++)";
        mJava->startBlock();
        writeJavaTestAndSetValid(p, "[j]", "[i * " + p.vectorWidth + " + j]");
        mJava->endBlock();
    }
}

void PermutationWriter::writeJavaAppendOutputToMessage(const ParameterDefinition& p,
                                                       const string& argsIndex,
                                                       const string& actualIndex,
                                                       bool verifierValidates) const {
    if (verifierValidates) {
        mJava->indent() << "message.append(\"Output " << p.variableName << ": \");\n";
        mJava->indent() << "appendVariableToMessage(message, args." << p.variableName << argsIndex
                        << ");\n";
        writeJavaAppendNewLineToMessage();
        if (p.isFloat16Parameter()) {
            writeJavaAppendNewLineToMessage();
            mJava->indent() << "message.append(\"Output " << p.variableName
                            << " (in double): \");\n";
            mJava->indent() << "appendVariableToMessage(message, args." << p.doubleVariableName
                            << ");\n";
            writeJavaAppendNewLineToMessage();
        }
    } else {
        mJava->indent() << "message.append(\"Expected output " << p.variableName << ": \");\n";
        mJava->indent() << "appendVariableToMessage(message, args." << p.variableName << argsIndex
                        << ");\n";
        writeJavaAppendNewLineToMessage();

        mJava->indent() << "message.append(\"Actual   output " << p.variableName << ": \");\n";
        mJava->indent() << "appendVariableToMessage(message, " << p.javaArrayName << actualIndex
                        << ");\n";

        if (p.isFloat16Parameter()) {
            writeJavaAppendNewLineToMessage();
            mJava->indent() << "message.append(\"Actual   output " << p.variableName
                            << " (in double): \");\n";
            mJava->indent() << "appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble("
                            << p.javaArrayName << actualIndex << "));\n";
        }

        writeJavaTestOneValue(p, argsIndex, actualIndex);
        mJava->startBlock();
        mJava->indent() << "message.append(\" FAIL\");\n";
        mJava->endBlock();
        writeJavaAppendNewLineToMessage();
    }
}

void PermutationWriter::writeJavaAppendInputToMessage(const ParameterDefinition& p,
                                                      const string& actual) const {
    mJava->indent() << "message.append(\"Input " << p.variableName << ": \");\n";
    mJava->indent() << "appendVariableToMessage(message, " << actual << ");\n";
    writeJavaAppendNewLineToMessage();
}

void PermutationWriter::writeJavaAppendNewLineToMessage() const {
    mJava->indent() << "message.append(\"\\n\");\n";
}

void PermutationWriter::writeJavaAppendVectorInputToMessage(const ParameterDefinition& p) const {
    if (p.mVectorSize == "1") {
        writeJavaAppendInputToMessage(p, p.javaArrayName + "[i]");
    } else {
        mJava->indent() << "for (int j = 0; j < " << p.mVectorSize << " ; j++)";
        mJava->startBlock();
        writeJavaAppendInputToMessage(p, p.javaArrayName + "[i * " + p.vectorWidth + " + j]");
        mJava->endBlock();
    }
}

void PermutationWriter::writeJavaAppendVectorOutputToMessage(const ParameterDefinition& p) const {
    if (p.mVectorSize == "1") {
        writeJavaAppendOutputToMessage(p, "", "[i]", false);
    } else {
        mJava->indent() << "for (int j = 0; j < " << p.mVectorSize << " ; j++)";
        mJava->startBlock();
        writeJavaAppendOutputToMessage(p, "[j]", "[i * " + p.vectorWidth + " + j]", false);
        mJava->endBlock();
    }
}

void PermutationWriter::writeJavaCallToRs(bool relaxed, bool generateCallToVerifier) const {
    string script = "script";
    if (relaxed) {
        script += "Relaxed";
    }

    mJava->indent() << "try";
    mJava->startBlock();

    for (auto p : mAllInputsAndOutputs) {
        if (p->isOutParameter) {
            writeJavaOutputAllocationDefinition(*p);
        }
    }

    for (auto p : mPermutation.getParams()) {
        if (p != mFirstInputParam) {
            mJava->indent() << script << ".set_" << p->rsAllocName << "(" << p->javaAllocName
                            << ");\n";
        }
    }

    mJava->indent() << script << ".forEach_" << mRsKernelName << "(";
    bool needComma = false;
    if (mFirstInputParam) {
        *mJava << mFirstInputParam->javaAllocName;
        needComma = true;
    }
    if (mReturnParam) {
        if (needComma) {
            *mJava << ", ";
        }
        *mJava << mReturnParam->variableName << ");\n";
    }

    if (generateCallToVerifier) {
        mJava->indent() << mJavaVerifyMethodName << "(";
        for (auto p : mAllInputsAndOutputs) {
            *mJava << p->variableName << ", ";
        }

        if (relaxed) {
            *mJava << "true";
        } else {
            *mJava << "false";
        }
        *mJava << ");\n";
    }
    mJava->decreaseIndent();
    mJava->indent() << "} catch (Exception e) {\n";
    mJava->increaseIndent();
    mJava->indent() << "throw new RSRuntimeException(\"RenderScript. Can't invoke forEach_"
                    << mRsKernelName << ": \" + e.toString());\n";
    mJava->endBlock();
}

/* Write the section of the .rs file for this permutation.
 *
 * We communicate the extra input and output parameters via global allocations.
 * For example, if we have a function that takes three arguments, two for input
 * and one for output:
 *
 * start:
 * name: gamn
 * ret: float3
 * arg: float3 a
 * arg: int b
 * arg: float3 *c
 * end:
 *
 * We'll produce:
 *
 * rs_allocation gAllocInB;
 * rs_allocation gAllocOutC;
 *
 * float3 __attribute__((kernel)) test_gamn_float3_int_float3(float3 inA, unsigned int x) {
 *    int inB;
 *    float3 outC;
 *    float2 out;
 *    inB = rsGetElementAt_int(gAllocInB, x);
 *    out = gamn(a, in_b, &outC);
 *    rsSetElementAt_float4(gAllocOutC, &outC, x);
 *    return out;
 * }
 *
 * We avoid re-using x and y from the definition because these have reserved
 * meanings in a .rs file.
 */
void PermutationWriter::writeRsSection(set<string>* rsAllocationsGenerated) const {
    // Write the allocation declarations we'll need.
    for (auto p : mPermutation.getParams()) {
        // Don't need allocation for one input and one return value.
        if (p != mFirstInputParam) {
            writeRsAllocationDefinition(*p, rsAllocationsGenerated);
        }
    }
    *mRs << "\n";

    // Write the function header.
    if (mReturnParam) {
        *mRs << mReturnParam->rsType;
    } else {
        *mRs << "void";
    }
    *mRs << " __attribute__((kernel)) " << mRsKernelName;
    *mRs << "(";
    bool needComma = false;
    if (mFirstInputParam) {
        *mRs << mFirstInputParam->rsType << " " << mFirstInputParam->variableName;
        needComma = true;
    }
    if (mPermutation.getOutputCount() > 1 || mPermutation.getInputCount() > 1) {
        if (needComma) {
            *mRs << ", ";
        }
        *mRs << "unsigned int x";
    }
    *mRs << ")";
    mRs->startBlock();

    // Write the local variable declarations and initializations.
    for (auto p : mPermutation.getParams()) {
        if (p == mFirstInputParam) {
            continue;
        }
        mRs->indent() << p->rsType << " " << p->variableName;
        if (p->isOutParameter) {
            *mRs << " = 0;\n";
        } else {
            *mRs << " = rsGetElementAt_" << p->rsType << "(" << p->rsAllocName << ", x);\n";
        }
    }

    // Write the function call.
    if (mReturnParam) {
        if (mPermutation.getOutputCount() > 1) {
            mRs->indent() << mReturnParam->rsType << " " << mReturnParam->variableName << " = ";
        } else {
            mRs->indent() << "return ";
        }
    }
    *mRs << mPermutation.getName() << "(";
    needComma = false;
    for (auto p : mPermutation.getParams()) {
        if (needComma) {
            *mRs << ", ";
        }
        if (p->isOutParameter) {
            *mRs << "&";
        }
        *mRs << p->variableName;
        needComma = true;
    }
    *mRs << ");\n";

    if (mPermutation.getOutputCount() > 1) {
        // Write setting the extra out parameters into the allocations.
        for (auto p : mPermutation.getParams()) {
            if (p->isOutParameter) {
                mRs->indent() << "rsSetElementAt_" << p->rsType << "(" << p->rsAllocName << ", ";
                // Check if we need to use '&' for this type of argument.
                char lastChar = p->variableName.back();
                if (lastChar >= '0' && lastChar <= '9') {
                    *mRs << "&";
                }
                *mRs << p->variableName << ", x);\n";
            }
        }
        if (mReturnParam) {
            mRs->indent() << "return " << mReturnParam->variableName << ";\n";
        }
    }
    mRs->endBlock();
}

void PermutationWriter::writeRsAllocationDefinition(const ParameterDefinition& param,
                                                    set<string>* rsAllocationsGenerated) const {
    if (!testAndSet(param.rsAllocName, rsAllocationsGenerated)) {
        *mRs << "rs_allocation " << param.rsAllocName << ";\n";
    }
}

// Open the mJavaFile and writes the header.
static bool startJavaFile(GeneratedFile* file, const Function& function, const string& directory,
                          const string& testName, const string& relaxedTestName) {
    const string fileName = testName + ".java";
    if (!file->start(directory, fileName)) {
        return false;
    }
    file->writeNotices();

    *file << "package android.renderscript.cts;\n\n";

    *file << "import android.renderscript.Allocation;\n";
    *file << "import android.renderscript.RSRuntimeException;\n";
    *file << "import android.renderscript.Element;\n";
    *file << "import android.renderscript.cts.Target;\n\n";
    *file << "import java.util.Arrays;\n\n";

    *file << "public class " << testName << " extends RSBaseCompute";
    file->startBlock();  // The corresponding endBlock() is in finishJavaFile()
    *file << "\n";

    file->indent() << "private ScriptC_" << testName << " script;\n";
    file->indent() << "private ScriptC_" << relaxedTestName << " scriptRelaxed;\n\n";

    file->indent() << "@Override\n";
    file->indent() << "protected void setUp() throws Exception";
    file->startBlock();

    file->indent() << "super.setUp();\n";
    file->indent() << "script = new ScriptC_" << testName << "(mRS);\n";
    file->indent() << "scriptRelaxed = new ScriptC_" << relaxedTestName << "(mRS);\n";

    file->endBlock();
    *file << "\n";
    return true;
}

// Write the test method that calls all the generated Check methods.
static void finishJavaFile(GeneratedFile* file, const Function& function,
                           const vector<string>& javaCheckMethods) {
    file->indent() << "public void test" << function.getCapitalizedName() << "()";
    file->startBlock();
    for (auto m : javaCheckMethods) {
        file->indent() << m << "();\n";
    }
    file->endBlock();

    file->endBlock();
}

// Open the script file and write its header.
static bool startRsFile(GeneratedFile* file, const Function& function, const string& directory,
                        const string& testName) {
    string fileName = testName + ".rs";
    if (!file->start(directory, fileName)) {
        return false;
    }
    file->writeNotices();

    *file << "#pragma version(1)\n";
    *file << "#pragma rs java_package_name(android.renderscript.cts)\n\n";
    return true;
}

// Write the entire *Relaxed.rs test file, as it only depends on the name.
static bool writeRelaxedRsFile(const Function& function, const string& directory,
                               const string& testName, const string& relaxedTestName) {
    string name = relaxedTestName + ".rs";

    GeneratedFile file;
    if (!file.start(directory, name)) {
        return false;
    }
    file.writeNotices();

    file << "#include \"" << testName << ".rs\"\n";
    file << "#pragma rs_fp_relaxed\n";
    file.close();
    return true;
}

/* Write the .java and the two .rs test files.  versionOfTestFiles is used to restrict which API
 * to test.
 */
static bool writeTestFilesForFunction(const Function& function, const string& directory,
                                      unsigned int versionOfTestFiles) {
    // Avoid creating empty files if we're not testing this function.
    if (!needTestFiles(function, versionOfTestFiles)) {
        return true;
    }

    const string testName = "Test" + function.getCapitalizedName();
    const string relaxedTestName = testName + "Relaxed";

    if (!writeRelaxedRsFile(function, directory, testName, relaxedTestName)) {
        return false;
    }

    GeneratedFile rsFile;    // The Renderscript test file we're generating.
    GeneratedFile javaFile;  // The Jave test file we're generating.
    if (!startRsFile(&rsFile, function, directory, testName)) {
        return false;
    }

    if (!startJavaFile(&javaFile, function, directory, testName, relaxedTestName)) {
        return false;
    }

    /* We keep track of the allocations generated in the .rs file and the argument classes defined
     * in the Java file, as we share these between the functions created for each specification.
     */
    set<string> rsAllocationsGenerated;
    set<string> javaGeneratedArgumentClasses;
    // Lines of Java code to invoke the check methods.
    vector<string> javaCheckMethods;

    for (auto spec : function.getSpecifications()) {
        if (spec->hasTests(versionOfTestFiles)) {
            for (auto permutation : spec->getPermutations()) {
                PermutationWriter w(*permutation, &rsFile, &javaFile);
                w.writeRsSection(&rsAllocationsGenerated);
                w.writeJavaSection(&javaGeneratedArgumentClasses);

                // Store the check method to be called.
                javaCheckMethods.push_back(w.getJavaCheckMethodName());
            }
        }
    }

    finishJavaFile(&javaFile, function, javaCheckMethods);
    // There's no work to wrap-up in the .rs file.

    rsFile.close();
    javaFile.close();
    return true;
}

bool generateTestFiles(const string& directory, unsigned int versionOfTestFiles) {
    bool success = true;
    for (auto f : systemSpecification.getFunctions()) {
        if (!writeTestFilesForFunction(*f.second, directory, versionOfTestFiles)) {
            success = false;
        }
    }
    return success;
}
