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

#include "ArrayType.h"
#include "CompoundType.h"

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

namespace android {

RefType::RefType() {
}

std::string RefType::typeName() const {
    return "ref" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
}

std::string RefType::getVtsType() const {
    return "TYPE_REF";
}

std::string RefType::getVtsValueName() const {
    return "ref_value";
}

bool RefType::isCompatibleElementType(Type *elementType) const {
    if (elementType->isScalar()) {
        return true;
    }
    if (elementType->isString()) {
        return true;
    }
    if (elementType->isEnum()) {
        return true;
    }
    if (elementType->isBitField()) {
        return true;
    }
    if (elementType->isCompoundType()
            && static_cast<CompoundType *>(elementType)->style() == CompoundType::STYLE_STRUCT) {
        return true;
    }
    if (elementType->isTemplatedType()) {
        return this->isCompatibleElementType(static_cast<TemplatedType *>(elementType)->getElementType());
    }
    if (elementType->isArray()) {
        return this->isCompatibleElementType(static_cast<ArrayType *>(elementType)->getElementType());
    }
    return false;
}

/* return something like "T const *".
 * The reason we don't return "const T *" is to handle cases like
 * ref<ref<ref<T>>> t_3ptr;
 * in this case the const's will get stacked on the left (const const const T *** t_3ptr)
 * but in this implementation it would be clearer (T const* const* const* t_3ptr) */
std::string RefType::getCppType(StorageMode /*mode*/, bool specifyNamespaces) const {
    return mElementType->getCppStackType(specifyNamespaces)
            + " const*";
}

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

void RefType::emitReaderWriter(
        Formatter &,
        const std::string &,
        const std::string &,
        bool,
        bool,
        ErrorMode) const {
    // RefType doesn't get read / written at this stage.
    return;
}

void RefType::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,
        "", // parentName
        ""); // offsetText
}

void RefType::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 {

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

    std::string baseType = getCppStackType();

    const std::string parcelObjDeref =
        parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;

    const std::string parcelObjPointer =
        parcelObjIsPointer ? parcelObj : ("&" + parcelObj);

    // as if nameIsPointer is false. Pointers are always pass by values,
    // so name is always the pointer value itself. Hence nameIsPointer = false.
    const std::string namePointer = "&" + name;
    const std::string handleName = "_hidl_" + sanitizedName + "__ref_handle";
    const std::string resolveBufName = "_hidl_" + sanitizedName + "__ref_resolve_buf";

    bool isEmbedded = (!parentName.empty() && !offsetText.empty());

    out << "size_t " << handleName << ";\n"
        << "bool " << resolveBufName << ";\n\n";

    out << "_hidl_err = ";

    if (isReader) {
        out << "::android::hardware::read"
            << (isEmbedded ? "Embedded" : "")
            << "ReferenceFromParcel<"
            << elementType
            << ">(const_cast<"
            << baseType
            << " *>("
            << namePointer
            << "),";
    } else {
        out << "::android::hardware::write"
            << (isEmbedded ? "Embedded" : "")
            << "ReferenceToParcel<"
            << elementType
            << ">("
            << name
            << ",";
    }

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

    out << (isReader ? parcelObjDeref : parcelObjPointer);
    if(isEmbedded)
        out << ",\n"
            << parentName
            << ",\n"
            << offsetText;

    out << ",\n&" + handleName;
    out << ",\n&" + resolveBufName;
    out << ");\n\n";

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

    handleError(out, mode);

    if(!mElementType->needsResolveReferences() && !mElementType->needsEmbeddedReadWrite())
        return; // no need to deal with element type recursively.

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

    if(mElementType->needsEmbeddedReadWrite()) {
        mElementType->emitReaderWriterEmbedded(
            out,
            0 /* depth */,
            name,
            sanitizedName,
            true /* nameIsPointer */, // for element type, name is a pointer.
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            handleName,
            "0 /* parentOffset */");
    }

    if(mElementType->needsResolveReferences()) {
        mElementType->emitResolveReferencesEmbedded(
            out,
            0 /* depth */,
            "(*" + name + ")",
            sanitizedName + "_deref",
            false /* nameIsPointer */,
                // must deref it and say false here, otherwise pointer to pointers don't work
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            handleName,
            "0 /* parentOffset */");
    }

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

bool RefType::needsResolveReferences() const {
    return true;
}

bool RefType::needsEmbeddedReadWrite() const {
    return false;
}

bool RefType::resultNeedsDeref() const {
    return false;
}

bool RefType::isJavaCompatible() const {
    return false;
}

bool RefType::containsPointer() const {
    return true;
}

}  // namespace android

