/*
 * 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 <hidl-util/Formatter.h>
#include <android-base/logging.h>

#include "ConstantExpression.h"

namespace android {

ArrayType::ArrayType(ArrayType *srcArray, ConstantExpression *size)
    : mElementType(srcArray->mElementType),
      mSizes(srcArray->mSizes) {
    prependDimension(size);
}

ArrayType::ArrayType(Type *elementType, ConstantExpression *size)
    : mElementType(elementType) {
    prependDimension(size);
}

void ArrayType::prependDimension(ConstantExpression *size) {
    mSizes.insert(mSizes.begin(), size);
}

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

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

void ArrayType::addNamedTypesToSet(std::set<const FQName> &set) const {
    mElementType->addNamedTypesToSet(set);
}

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

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

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::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 ? "->" : ".");

    if (isReader) {

        out << name
            << " = ("
            << getCppResultType()
            << ")"
            << parcelObjDeref
            << "readBuffer(&"
            << parentName
            << ");\n\n";

        out << "if (" << name << " == nullptr) {\n";

        out.indent();

        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
        handleError2(out, mode);

        out.unindent();
        out << "}\n\n";
    } else {
        size_t numArrayElements = 1;
        for (auto size : mSizes) {
            numArrayElements *= size->castSizeT();
        }

        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";
}


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

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

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

void ArrayType::emitJavaReaderWriter(
        Formatter &out,
        const std::string &parcelObj,
        const std::string &argName,
        bool isReader) const {
    if (isReader) {
        out << "new "
            << getJavaType(true /* forInitializer */)
            << ";\n";
    }

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

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

    if (isReader) {
        out << parcelObj
            << ".readBuffer();\n";
    } else {
        size_t align, size;
        getAlignmentAndSize(&align, &size);

        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";

    std::string indexString;
    for (size_t dim = 0; dim < mSizes.size(); ++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";
    }

    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";

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

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

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

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

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

