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

#include "HidlTypeAssertion.h"

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

namespace android {

FmqType::FmqType(const char *nsp, const char *name)
    : mNamespace(nsp), mName(name) {
}

std::string FmqType::fullName() const {
    return mNamespace +
            (mNamespace.empty() ? "" : "::") +
            mName + "<" + mElementType->getCppStackType(true) + ">";
}

std::string FmqType::getCppType(
        StorageMode mode,
        bool) const {

    const std::string base = fullName();

    switch (mode) {
        case StorageMode_Stack:
            return base;

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

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

void FmqType::emitReaderWriter(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {
    const std::string parentName = "_hidl_" + name + "_parent";

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

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

    if (isReader) {
        out << "_hidl_err = "
            << parcelObjDeref
            << "readBuffer("
            << "sizeof(*"
            << name
            << "), &"
            << parentName
            << ", "
            << " reinterpret_cast<const void **>("
            << "&" << name
            << "));\n\n";

        handleError(out, mode);
    } 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 FmqType::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 {
    emitReaderWriterEmbeddedForTypeName(
            out,
            name,
            nameIsPointer,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            parentName,
            offsetText,
            fullName(),
            "" /* childName */,
            mNamespace);
}

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

// All MQDescriptor<T, flavor> have the same size.
static HidlTypeAssertion assertion(
        "MQDescriptor<char, ::android::hardware::kSynchronizedReadWrite>", 32);

void FmqType::getAlignmentAndSize(
        size_t *align, size_t *size) const {
    *align = 8;  // MQDescriptor<>
    *size = assertion.size();
}

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

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

bool FmqType::isCompatibleElementType(Type *elementType) const {
    return (!elementType->isInterface() && !elementType->needsEmbeddedReadWrite());
}

std::string FmqType::getVtsType() const {
    if (mName == "MQDescriptorSync") {
        return "TYPE_FMQ_SYNC";
    } else if (mName == "MQDescriptorUnsync") {
        return "TYPE_FMQ_UNSYNC";
    } else {
        LOG(ERROR) << "Invalid fmq type name.\n";
    }
    return "";
}

std::string FmqType::getVtsValueName() const {
    return "fmq_value";
}
}  // namespace android

