/*
 * Copyright (C) 2016 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 "ArrayType.h"

#include <android-base/logging.h>
#include <hidl-util/Formatter.h>
#include <iostream>

#include "ConstantExpression.h"

namespace android {

ArrayType::ArrayType(const Reference<Type>& elementType, ConstantExpression* size, Scope* parent)
    : Type(parent), mElementType(elementType), mSizes{size} {
    CHECK(!elementType.isEmptyReference());
}

void ArrayType::appendDimension(ConstantExpression *size) {
    mSizes.push_back(size);
}

size_t ArrayType::countDimensions() const {
    return mSizes.size();
}

bool ArrayType::isArray() const {
    return true;
}

bool ArrayType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
    return mElementType->canCheckEquality(visited);
}

const Type* ArrayType::getElementType() const {
    return mElementType.get();
}

std::string ArrayType::typeName() const {
    if (dimension() == 1) {
        return "array of " + mElementType->typeName();
    }

    return std::to_string(dimension()) + "d array of " + mElementType->typeName();
}

std::vector<const Reference<Type>*> ArrayType::getReferences() const {
    return {&mElementType};
}

std::vector<const ConstantExpression*> ArrayType::getConstantExpressions() const {
    std::vector<const ConstantExpression*> ret;
    ret.insert(ret.end(), mSizes.begin(), mSizes.end());
    return ret;
}

status_t ArrayType::resolveInheritance() {
    // Resolve for typedefs
    while (mElementType->isArray()) {
        ArrayType* innerArray = static_cast<ArrayType*>(mElementType.get());
        mSizes.insert(mSizes.end(), innerArray->mSizes.begin(), innerArray->mSizes.end());
        mElementType = innerArray->mElementType;
    }
    return Type::resolveInheritance();
}

status_t ArrayType::validate() const {
    CHECK(!mElementType->isArray());

    if (mElementType->isBinder()) {
        std::cerr << "ERROR: Arrays of interface types are not supported"
                  << " at " << mElementType.location() << "\n";

        return UNKNOWN_ERROR;
    }
    return Type::validate();
}

std::string ArrayType::getCppType(StorageMode mode,
                                  bool specifyNamespaces) const {
    const std::string base = mElementType->getCppStackType(specifyNamespaces);

    std::string space = specifyNamespaces ? "::android::hardware::" : "";
    std::string arrayType = space + "hidl_array<" + base;

    for (size_t i = 0; i < mSizes.size(); ++i) {
        arrayType += ", ";
        arrayType += mSizes[i]->cppValue();

        if (!mSizes[i]->descriptionIsTrivial()) {
            arrayType += " /* ";
            arrayType += mSizes[i]->description();
            arrayType += " */";
        }
    }

    arrayType += ">";

    switch (mode) {
        case StorageMode_Stack:
            return arrayType;

        case StorageMode_Argument:
            return "const " + arrayType + "&";

        case StorageMode_Result:
            return "const " + arrayType + "*";
    }

    CHECK(!"Should not be here");
}

std::string ArrayType::getInternalDataCppType() const {
    std::string result = mElementType->getCppStackType();
    for (size_t i = 0; i < mSizes.size(); ++i) {
        result += "[";
        result += mSizes[i]->cppValue();
        result += "]";
    }
    return result;
}

std::string ArrayType::getJavaType(bool forInitializer) const {
    std::string base =
        mElementType->getJavaType(forInitializer);

    for (size_t i = 0; i < mSizes.size(); ++i) {
        base += "[";

        if (forInitializer) {
            base += mSizes[i]->javaValue();
        }

        if (!forInitializer || !mSizes[i]->descriptionIsTrivial()) {
            if (forInitializer)
                base += " ";
            base += "/* " + mSizes[i]->description() + " */";
        }

        base += "]";
    }

    return base;
}

std::string ArrayType::getJavaWrapperType() const {
    return mElementType->getJavaWrapperType();
}

std::string ArrayType::getVtsType() const {
    return "TYPE_ARRAY";
}

void ArrayType::emitReaderWriter(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {
    std::string baseType = mElementType->getCppStackType();

    const std::string parentName = "_hidl_" + name + "_parent";

    out << "size_t " << parentName << ";\n\n";

    const std::string parcelObjDeref =
        parcelObj + (parcelObjIsPointer ? "->" : ".");

    size_t numArrayElements = 1;
    for (auto size : mSizes) {
        numArrayElements *= size->castSizeT();
    }
    if (isReader) {
        out << "_hidl_err = "
            << parcelObjDeref
            << "readBuffer("
            << numArrayElements
            << " * sizeof("
            << baseType
            << "), &"
            << parentName
            << ", "
            << " reinterpret_cast<const void **>("
            << "&" << name
            << "));\n\n";

        handleError(out, mode);
    } else {

        out << "_hidl_err = "
            << parcelObjDeref
            << "writeBuffer("
            << name
            << ".data(), "
            << numArrayElements
            << " * sizeof("
            << baseType
            << "), &"
            << parentName
            << ");\n";

        handleError(out, mode);
    }

    emitReaderWriterEmbedded(
            out,
            0 /* depth */,
            name,
            name /* sanitizedName */,
            isReader /* nameIsPointer */,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            parentName,
            "0 /* parentOffset */");
}

void ArrayType::emitReaderWriterEmbedded(
        Formatter &out,
        size_t depth,
        const std::string &name,
        const std::string &sanitizedName,
        bool nameIsPointer,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode,
        const std::string &parentName,
        const std::string &offsetText) const {
    if (!mElementType->needsEmbeddedReadWrite()) {
        return;
    }

    const std::string nameDeref = name + (nameIsPointer ? "->" : ".");

    std::string baseType = mElementType->getCppStackType();

    std::string iteratorName = "_hidl_index_" + std::to_string(depth);

    out << "for (size_t "
        << iteratorName
        << " = 0; "
        << iteratorName
        << " < "
        << dimension()
        << "; ++"
        << iteratorName
        << ") {\n";

    out.indent();

    mElementType->emitReaderWriterEmbedded(
            out,
            depth + 1,
            nameDeref + "data()[" + iteratorName + "]",
            sanitizedName + "_indexed",
            false /* nameIsPointer */,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            parentName,
            offsetText
                + " + " + iteratorName + " * sizeof("
                + baseType
                + ")");

    out.unindent();

    out << "}\n\n";
}

void ArrayType::emitResolveReferences(
            Formatter &out,
            const std::string &name,
            bool nameIsPointer,
            const std::string &parcelObj,
            bool parcelObjIsPointer,
            bool isReader,
            ErrorMode mode) const {
    emitResolveReferencesEmbedded(
        out,
        0 /* depth */,
        name,
        name /* sanitizedName */,
        nameIsPointer,
        parcelObj,
        parcelObjIsPointer,
        isReader,
        mode,
        "_hidl_" + name + "_parent",
        "0 /* parentOffset */");
}

void ArrayType::emitResolveReferencesEmbedded(
            Formatter &out,
            size_t depth,
            const std::string &name,
            const std::string &sanitizedName,
            bool nameIsPointer,
            const std::string &parcelObj,
            bool parcelObjIsPointer,
            bool isReader,
            ErrorMode mode,
            const std::string &parentName,
            const std::string &offsetText) const {
    CHECK(needsResolveReferences() && mElementType->needsResolveReferences());

    const std::string nameDeref = name + (nameIsPointer ? "->" : ".");

    std::string baseType = mElementType->getCppStackType();

    std::string iteratorName = "_hidl_index_" + std::to_string(depth);

    out << "for (size_t "
        << iteratorName
        << " = 0; "
        << iteratorName
        << " < "
        << dimension()
        << "; ++"
        << iteratorName
        << ") {\n";

    out.indent();

    mElementType->emitResolveReferencesEmbedded(
        out,
        depth + 1,
        nameDeref + "data()[" + iteratorName + "]",
        sanitizedName + "_indexed",
        false /* nameIsPointer */,
        parcelObj,
        parcelObjIsPointer,
        isReader,
        mode,
        parentName,
        offsetText + " + " + iteratorName + " * sizeof("
        + baseType
        + ")");

    out.unindent();

    out << "}\n\n";
}

void ArrayType::emitJavaDump(
        Formatter &out,
        const std::string &streamName,
        const std::string &name) const {
    out << streamName << ".append(java.util.Arrays."
        << (countDimensions() > 1 ? "deepToString" : "toString")
        << "("
        << name << "));\n";
}


bool ArrayType::needsEmbeddedReadWrite() const {
    return mElementType->needsEmbeddedReadWrite();
}

bool ArrayType::deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const {
    if (mElementType->needsResolveReferences(visited)) {
        return true;
    }
    return Type::deepNeedsResolveReferences(visited);
}

bool ArrayType::resultNeedsDeref() const {
    return true;
}

void ArrayType::emitJavaReaderWriter(
        Formatter &out,
        const std::string &parcelObj,
        const std::string &argName,
        bool isReader) const {
    size_t align, size;
    getAlignmentAndSize(&align, &size);

    if (isReader) {
        out << "new "
            << getJavaType(true /* forInitializer */)
            << ";\n";
    }

    out << "{\n";
    out.indent();

    out << "android.os.HwBlob _hidl_blob = ";

    if (isReader) {
        out << parcelObj
            << ".readBuffer("
            << size
            << " /* size */);\n";
    } else {
        out << "new android.os.HwBlob("
            << size
            << " /* size */);\n";
    }

    emitJavaFieldReaderWriter(
            out,
            0 /* depth */,
            parcelObj,
            "_hidl_blob",
            argName,
            "0 /* offset */",
            isReader);

    if (!isReader) {
        out << parcelObj << ".writeBuffer(_hidl_blob);\n";
    }

    out.unindent();
    out << "}\n";
}

void ArrayType::emitJavaFieldInitializer(
        Formatter &out, const std::string &fieldName) const {
    std::string typeName = getJavaType(false /* forInitializer */);
    std::string initName = getJavaType(true /* forInitializer */);

    out << "final "
        << typeName
        << " "
        << fieldName
        << " = new "
        << initName
        << ";\n";
}

void ArrayType::emitJavaFieldReaderWriter(
        Formatter &out,
        size_t depth,
        const std::string &parcelName,
        const std::string &blobName,
        const std::string &fieldName,
        const std::string &offset,
        bool isReader) const {
    out << "{\n";
    out.indent();

    std::string offsetName = "_hidl_array_offset_" + std::to_string(depth);
    out << "long " << offsetName << " = " << offset << ";\n";

    const bool isPrimitiveArray = mElementType->isScalar();

    /* If the element type corresponds to a Java primitive type we can optimize
       the innermost loop by copying a linear range of memory instead of doing
       a per-element copy. As a result the outer nested loop does not include
       the final dimension. */
    const size_t loopDimensions = mSizes.size() - (isPrimitiveArray ? 1 : 0);

    std::string indexString;
    for (size_t dim = 0; dim < loopDimensions; ++dim) {
        std::string iteratorName =
            "_hidl_index_" + std::to_string(depth) + "_" + std::to_string(dim);

        out << "for (int "
            << iteratorName
            << " = 0; "
            << iteratorName
            << " < "
            << mSizes[dim]->javaValue()
            << "; ++"
            << iteratorName
            << ") {\n";

        out.indent();

        indexString += "[" + iteratorName + "]";
    }

    if (isReader && mElementType->isCompoundType()) {
        std::string typeName =
            mElementType->getJavaType(false /* forInitializer */);

        out << fieldName
            << indexString
            << " = new "
            << typeName
            << "();\n";
    }

    if (!isPrimitiveArray) {
        mElementType->emitJavaFieldReaderWriter(
                out,
                depth + 1,
                parcelName,
                blobName,
                fieldName + indexString,
                offsetName,
                isReader);

        size_t elementAlign, elementSize;
        mElementType->getAlignmentAndSize(&elementAlign, &elementSize);

        out << offsetName << " += " << std::to_string(elementSize) << ";\n";
    } else {
        if (isReader) {
            out << blobName
                << ".copyTo"
                << mElementType->getJavaSuffix()
                << "Array("
                << offsetName
                << ", "
                << fieldName
                << indexString
                << ", "
                << mSizes.back()->javaValue()
                << " /* size */);\n";
        } else {
            out << blobName
                << ".put"
                << mElementType->getJavaSuffix()
                << "Array("
                << offsetName
                << ", "
                << fieldName
                << indexString
                << ");\n";
        }

        size_t elementAlign, elementSize;
        mElementType->getAlignmentAndSize(&elementAlign, &elementSize);

        out << offsetName
            << " += "
            << mSizes.back()->javaValue()
            << " * "
            << elementSize
            << ";\n";
    }

    for (size_t dim = 0; dim < loopDimensions; ++dim) {
        out.unindent();
        out << "}\n";
    }

    out.unindent();
    out << "}\n";
}

void ArrayType::emitVtsTypeDeclarations(Formatter& out) const {
    out << "type: " << getVtsType() << "\n";
    out << "vector_size: " << mSizes[0]->value() << "\n";
    out << "vector_value: {\n";
    out.indent();
    // Simple array case.
    if (mSizes.size() == 1) {
        mElementType->emitVtsTypeDeclarations(out);
    } else {  // Multi-dimension array case.
        for (size_t index = 1; index < mSizes.size(); index++) {
            out << "type: " << getVtsType() << "\n";
            out << "vector_size: " << mSizes[index]->value() << "\n";
            out << "vector_value: {\n";
            out.indent();
            if (index == mSizes.size() - 1) {
                mElementType->emitVtsTypeDeclarations(out);
            }
        }
    }
    for (size_t index = 0; index < mSizes.size(); index++) {
        out.unindent();
        out << "}\n";
    }
}

bool ArrayType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
    if (!mElementType->isJavaCompatible(visited)) {
        return false;
    }
    return Type::deepIsJavaCompatible(visited);
}

bool ArrayType::deepContainsPointer(std::unordered_set<const Type*>* visited) const {
    if (mElementType->containsPointer(visited)) {
        return true;
    }
    return Type::deepContainsPointer(visited);
}

void ArrayType::getAlignmentAndSize(size_t *align, size_t *size) const {
    mElementType->getAlignmentAndSize(align, size);

    for (auto sizeInDimension : mSizes) {
        (*size) *= sizeInDimension->castSizeT();
    }
}

size_t ArrayType::dimension() const {
    size_t numArrayElements = 1;
    for (auto size : mSizes) {
        numArrayElements *= size->castSizeT();
    }
    return numArrayElements;
}

}  // namespace android

