/*
 * 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 "VectorType.h"

#include "ArrayType.h"

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

namespace android {

VectorType::VectorType() {
}

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

bool VectorType::isVector() const {
    return true;
}

bool VectorType::isVectorOfBinders() const {
    return mElementType->isBinder();
}

std::string VectorType::getCppType(StorageMode mode,
                                   std::string *extra,
                                   bool specifyNamespaces) const {
    std::string elementExtra;
    const std::string elementBase =
        mElementType->getCppType(&elementExtra, specifyNamespaces);

    const std::string base =
          std::string(specifyNamespaces ? "::android::hardware::" : "")
        + "hidl_vec<"
        + mElementType->getCppType(extra, specifyNamespaces)
        + (*extra)
        + ">";

    extra->clear();

    switch (mode) {
        case StorageMode_Stack:
            return base;

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

        case StorageMode_Result:
        {
            if (isVectorOfBinders()) {
                return base;
            }

            return "const " + base + "*";
        }
    }
}

std::string VectorType::getJavaType(
        std::string *extra, bool /* forInitializer */) const {
    extra->clear();

    std::string elementExtra;
    std::string elementJavaType = mElementType->getJavaType(&elementExtra);

    CHECK(mElementType->isArray() || elementExtra.empty());

    return "ArrayList<"
        + (mElementType->isArray()
                ? elementJavaType : mElementType->getJavaWrapperType())
        + elementExtra
        + ">";
}

std::string VectorType::getVtsType() const {
    return "TYPE_VECTOR";
}

void VectorType::emitReaderWriter(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {
    if (isVectorOfBinders()) {
        emitReaderWriterForVectorOfBinders(
                out, name, parcelObj, parcelObjIsPointer, isReader, mode);

        return;
    }

    std::string baseExtra;
    std::string baseType = mElementType->getCppType(&baseExtra);

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

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

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

    if (isReader) {
        out << name
            << " = (const ::android::hardware::hidl_vec<"
            << baseType
            << baseExtra
            << "> *)"
            << 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 {
        out << "_hidl_err = "
            << parcelObjDeref
            << "writeBuffer(&"
            << name
            << ", sizeof("
            << name
            << "), &"
            << parentName
            << ");\n";

        handleError(out, mode);
    }

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

void VectorType::emitReaderWriterForVectorOfBinders(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {
    const std::string parcelObjDeref =
        parcelObj + (parcelObjIsPointer ? "->" : ".");

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

        const std::string sizeName = "_hidl_" + name + "_size";

        out << "uint64_t "
            << sizeName
            << ";\n";

        out << "_hidl_err = "
            << parcelObjDeref
            << "readUint64(&"
            << sizeName
            << ");\n";

        handleError(out, mode);

        out << name
            << ".resize("
            << sizeName
            << ");\n\n"
            << "for (size_t _hidl_index = 0; _hidl_index < "
            << sizeName
            << "; ++_hidl_index) {\n";

        out.indent();

        std::string extra;
        out << mElementType->getCppType(&extra, true /* specifyNamespaces */)
            << " _hidl_binder;\n";

        mElementType->emitReaderWriter(
                out,
                "_hidl_binder",
                parcelObj,
                parcelObjIsPointer,
                isReader,
                mode);

        out << name
            << "[_hidl_index] = _hidl_binder;\n";

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

        out.unindent();
        out << "}\n";
    } else {
        out << "_hidl_err = "
            << parcelObjDeref
            << "writeUint64("
            << name
            << ".size());\n";

        handleError(out, mode);

        out << "for (size_t _hidl_index = 0; _hidl_index < "
            << name
            << ".size(); ++_hidl_index) {\n";

        out.indent();

        mElementType->emitReaderWriter(
                out,
                name + "[_hidl_index]",
                parcelObj,
                parcelObjIsPointer,
                isReader,
                mode);

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

void VectorType::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 {
    std::string baseExtra;
    std::string baseType = Type::getCppType(&baseExtra);

    const std::string childName = "_hidl_" + sanitizedName + "_child";
    out << "size_t " << childName << ";\n\n";

    emitReaderWriterEmbeddedForTypeName(
            out,
            name,
            nameIsPointer,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            parentName,
            offsetText,
            baseType,
            childName);

    if (!mElementType->needsEmbeddedReadWrite()) {
        return;
    }

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

    baseType = mElementType->getCppType(&baseExtra);

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

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

    out.indent();

    mElementType->emitReaderWriterEmbedded(
            out,
            depth + 1,
            (nameIsPointer ? "(*" + name + ")" : name)
                + "[" + iteratorName + "]",
            sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
            false /* nameIsPointer */,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            childName,
            iteratorName + " * sizeof(" + baseType + baseExtra + ")");

    out.unindent();

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

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

void VectorType::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 {
    emitResolveReferencesEmbeddedHelper(
        out, depth, name, sanitizedName, nameIsPointer, parcelObj,
        parcelObjIsPointer, isReader, mode, "", "");
}

bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
    // parentName and offsetText is not used in emitResolveReferencesEmbedded
    return false;
}

void VectorType::emitResolveReferencesEmbeddedHelper(
            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 &childName,
            const std::string &childOffsetText) const {
    CHECK(needsResolveReferences() && mElementType->needsResolveReferences());

    const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
    std::string elementExtra;
    std::string elementType = mElementType->getCppType(&elementExtra);

    std::string myChildName = childName, myChildOffset = childOffsetText;

    if(myChildName.empty() && myChildOffset.empty()) {
        myChildName = "_hidl_" + sanitizedName + "_child";
        myChildOffset = "0";

        out << "size_t " << myChildName << ";\n";
        out << "_hidl_err = " << nameDeref << "findInParcel("
            << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
            << "&" << myChildName
            << ");\n";

        handleError(out, mode);
    }

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

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

    out.indent();

    mElementType->emitResolveReferencesEmbedded(
        out,
        depth + 1,
        (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
        sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
        false /* nameIsPointer */,
        parcelObj,
        parcelObjIsPointer,
        isReader,
        mode,
        myChildName,
        myChildOffset + " + " +
                iteratorName + " * sizeof(" + elementType + elementExtra + ")");

    out.unindent();

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

void VectorType::emitJavaReaderWriter(
        Formatter &out,
        const std::string &parcelObj,
        const std::string &argName,
        bool isReader) const {
    if (mElementType->isCompoundType()) {
        std::string extra;  // unused, because CompoundType leaves this empty.

        if (isReader) {
            out << mElementType->getJavaType(&extra)
                << ".readVectorFromParcel("
                << parcelObj
                << ");\n";
        } else {
            out << mElementType->getJavaType(&extra)
                << ".writeVectorToParcel("
                << parcelObj
                << ", "
                << argName
                << ");\n";
        }

        return;
    }

    if (mElementType->isArray()) {
        if (isReader) {
            std::string extra;
            out << " new "
                << getJavaType(&extra, false /* forInitializer */)
                << "();\n";
        }

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

        out << "HwBlob _hidl_blob = ";

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

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

        return;
    }

    emitJavaReaderWriterWithSuffix(
            out,
            parcelObj,
            argName,
            isReader,
            mElementType->getJavaSuffix() + "Vector",
            "" /* extra */);
}

void VectorType::emitJavaFieldInitializer(
        Formatter &out, const std::string &fieldName) const {
    std::string extra;
    std::string javaType = getJavaType(&extra, false /* forInitializer */);

    out << "final "
        << javaType
        << " "
        << fieldName
        << " = new "
        << javaType
        << "();\n";
}

void VectorType::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 {
    VectorType::EmitJavaFieldReaderWriterForElementType(
            out,
            depth,
            mElementType,
            parcelName,
            blobName,
            fieldName,
            offset,
            isReader);
}

// static
void VectorType::EmitJavaFieldReaderWriterForElementType(
        Formatter &out,
        size_t depth,
        const Type *elementType,
        const std::string &parcelName,
        const std::string &blobName,
        const std::string &fieldName,
        const std::string &offset,
        bool isReader) {
    if (isReader) {
        out << "{\n";
        out.indent();

        out << "HwBlob childBlob = "
            << parcelName
            << ".readEmbeddedBuffer(\n";

        out.indent();
        out.indent();

        out << blobName
            << ".handle(),\n"
            << offset
            << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";

        out.unindent();
        out.unindent();

        out << fieldName << ".clear();\n";
        out << "long _hidl_vec_size = "
            << blobName
            << ".getInt64("
            << offset
            << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";

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

        out << "for (int "
            << iteratorName
            << " = 0; "
            << iteratorName
            << " < _hidl_vec_size; "
            << "++"
            << iteratorName
            << ") {\n";

        out.indent();

        elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");

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

        elementType->emitJavaFieldReaderWriter(
                out,
                depth + 1,
                parcelName,
                "childBlob",
                "_hidl_vec_element",
                iteratorName + " * " + std::to_string(elementSize),
                true /* isReader */);

        out << fieldName
            << ".add(_hidl_vec_element);\n";

        out.unindent();

        out << "}\n";

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

        return;
    }

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

    out << "long _hidl_vec_size = "
        << fieldName
        << ".size();\n";

    out << blobName
        << ".putInt64("
        << offset
        << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";

    out << blobName
        << ".putBool("
        << offset
        << " + 16 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";

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

    // XXX make HwBlob constructor take a long instead of an int?
    out << "HwBlob childBlob = new HwBlob((int)(_hidl_vec_size * "
        << elementSize
        << "));\n";

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

    out << "for (int "
        << iteratorName
        << " = 0; "
        << iteratorName
        << " < _hidl_vec_size; "
        << "++"
        << iteratorName
        << ") {\n";

    out.indent();

    elementType->emitJavaFieldReaderWriter(
            out,
            depth + 1,
            parcelName,
            "childBlob",
            fieldName + ".get(" + iteratorName + ")",
            iteratorName + " * " + std::to_string(elementSize),
            false /* isReader */);

    out.unindent();

    out << "}\n";

    out << blobName
        << ".putBlob("
        << offset
        << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";

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

bool VectorType::needsEmbeddedReadWrite() const {
    return true;
}

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

bool VectorType::resultNeedsDeref() const {
    return !isVectorOfBinders();
}

status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
    out << "type: " << getVtsType() << "\n";
    out << "vector_value: {\n";
    out.indent();
    status_t err = mElementType->emitVtsTypeDeclarations(out);
    if (err != OK) {
        return err;
    }
    out.unindent();
    out << "}\n";
    return OK;
}

status_t VectorType::emitVtsAttributeType(Formatter &out) const {
    out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
    out.indent();
    status_t status = mElementType->emitVtsAttributeType(out);
    if (status != OK) {
        return status;
    }
    out.unindent();
    out << "}\n";
    return OK;
}

bool VectorType::isJavaCompatible() const {
    if (!mElementType->isJavaCompatible()) {
        return false;
    }

    if (mElementType->isArray()) {
        return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
    }

    if (mElementType->isVector()) {
        return false;
    }

    if (isVectorOfBinders()) {
        return false;
    }

    return true;
}

void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
    *align = 8;  // hidl_vec<T>
    *size = 24;
}

}  // namespace android

