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

#include "Coordinator.h"
#include "Interface.h"
#include "Method.h"
#include "Scope.h"

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

namespace android {

void AST::emitJavaReaderWriter(
        Formatter &out,
        const std::string &parcelObj,
        const TypedVar *arg,
        bool isReader) const {
    if (isReader) {
        out << arg->type().getJavaType()
            << " "
            << arg->name()
            << " = ";
    }

    arg->type().emitJavaReaderWriter(out, parcelObj, arg->name(), isReader);
}

status_t AST::generateJavaTypes(
        const std::string &outputPath, const std::string &limitToType) const {
    // Splits types.hal up into one java file per declared type.

    for (const auto &type : mRootScope->getSubTypes()) {
        std::string typeName = type->localName();

        if (type->isTypeDef()) {
            continue;
        }

        if (!limitToType.empty() && typeName != limitToType) {
            continue;
        }

        std::string path = outputPath;
        path.append(mCoordinator->convertPackageRootToPath(mPackage));
        path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
        path.append(typeName);
        path.append(".java");

        CHECK(Coordinator::MakeParentHierarchy(path));
        FILE *file = fopen(path.c_str(), "w");

        if (file == NULL) {
            return -errno;
        }

        Formatter out(file);

        std::vector<std::string> packageComponents;
        getPackageAndVersionComponents(
                &packageComponents, true /* cpp_compatible */);

        out << "package " << mPackage.javaPackage() << ";\n\n";

        for (const auto &item : mImportedNamesForJava) {
            out << "import " << item.javaName() << ";\n";
        }
        out << "\n";

        status_t err =
            type->emitJavaTypeDeclarations(out, true /* atTopLevel */);

        if (err != OK) {
            return err;
        }
    }

    return OK;
}

status_t AST::generateJava(
        const std::string &outputPath, const std::string &limitToType) const {
    if (!isJavaCompatible()) {
        fprintf(stderr,
                "ERROR: This interface is not Java compatible. The Java backend"
                " does NOT support union types nor native handles. "
                "In addition, vectors of arrays are limited to at most "
                "one-dimensional arrays and vectors of {vectors,interfaces} are"
                " not supported.\n");

        return UNKNOWN_ERROR;
    }

    std::string ifaceName;
    if (!AST::isInterface(&ifaceName)) {
        return generateJavaTypes(outputPath, limitToType);
    }

    const Interface *iface = mRootScope->getInterface();

    const std::string baseName = iface->getBaseName();

    std::string path = outputPath;
    path.append(mCoordinator->convertPackageRootToPath(mPackage));
    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
    path.append(ifaceName);
    path.append(".java");

    CHECK(Coordinator::MakeParentHierarchy(path));
    FILE *file = fopen(path.c_str(), "w");

    if (file == NULL) {
        return -errno;
    }

    Formatter out(file);

    std::vector<std::string> packageComponents;
    getPackageAndVersionComponents(
            &packageComponents, true /* cpp_compatible */);

    out << "package " << mPackage.javaPackage() << ";\n\n";

    for (const auto &item : mImportedNamesForJava) {
        out << "import " << item.javaName() << ";\n";
    }

    if (!mImportedNamesForJava.empty()) {
        out << "\n";
    }

    out.setNamespace(mPackage.javaPackage() + ".");

    const Interface *superType = iface->superType();

    out << "public interface " << ifaceName << " extends ";

    if (superType != NULL) {
        out << superType->fullJavaName();
    } else {
        out << "android.os.IHwInterface";
    }

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

    out << "public static final String kInterfaceName = \""
        << mPackage.string()
        << "::"
        << ifaceName
        << "\";\n\n";

    out << "public static "
        << ifaceName
        << " asInterface(android.os.IHwBinder binder) {\n";

    out.indent();

    out << "if (binder == null) {\n";
    out.indent();
    out << "return null;\n";
    out.unindent();
    out << "}\n\n";

    out << "android.os.IHwInterface iface =\n";
    out.indent();
    out.indent();
    out << "binder.queryLocalInterface(kInterfaceName);\n\n";
    out.unindent();
    out.unindent();

    out << "if ((iface != null) && (iface instanceof "
        << ifaceName
        << ")) {\n";

    out.indent();
    out << "return (" << ifaceName << ")iface;\n";
    out.unindent();
    out << "}\n\n";

    out << "return new " << ifaceName << ".Proxy(binder);\n";

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

    out << "public android.os.IHwBinder asBinder();\n\n";

    out << "public static "
        << ifaceName
        << " getService(String serviceName) {\n";

    out.indent();

    out << "return "
        << ifaceName
        << ".asInterface(android.os.HwBinder.getService(\""
        << iface->fqName().string()
        << "\",serviceName));\n";

    out.unindent();

    out << "}\n\n";

    status_t err = emitJavaTypeDeclarations(out);

    if (err != OK) {
        return err;
    }

    for (const auto &method : iface->methods()) {
        const bool returnsValue = !method->results().empty();
        const bool needsCallback = method->results().size() > 1;

        if (needsCallback) {
            out << "\npublic abstract class "
                << method->name()
                << "Callback {\n";

            out.indent();

            out << "public abstract void onValues("
                << Method::GetJavaArgSignature(method->results())
                << ");\n";

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

        if (returnsValue && !needsCallback) {
            out << method->results()[0]->type().getJavaType();
        } else {
            out << "void";
        }

        out << " "
            << method->name()
            << "("
            << Method::GetJavaArgSignature(method->args());

        if (needsCallback) {
            if (!method->args().empty()) {
                out << ", ";
            }

            out << method->name()
                << "Callback cb";
        }

        out << ");\n";
    }

    out << "\npublic static final class Proxy implements "
        << ifaceName
        << " {\n";

    out.indent();

    out << "private android.os.IHwBinder mRemote;\n\n";
    out << "public Proxy(android.os.IHwBinder remote) {\n";
    out.indent();
    out << "mRemote = remote;\n";
    out.unindent();
    out << "}\n\n";

    out << "public android.os.IHwBinder asBinder() {\n";
    out.indent();
    out << "return mRemote;\n";
    out.unindent();
    out << "}\n\n";

    const Interface *prevInterface = nullptr;
    for (const auto &tuple : iface->allMethodsFromRoot()) {
        const Method *method = tuple.method();
        const Interface *superInterface = tuple.interface();
        if (prevInterface != superInterface) {
            out << "// Methods from "
                << superInterface->fullName()
                << " follow.\n";
            prevInterface = superInterface;
        }
        const bool returnsValue = !method->results().empty();
        const bool needsCallback = method->results().size() > 1;

        out << "public ";
        if (returnsValue && !needsCallback) {
            out << method->results()[0]->type().getJavaType();
        } else {
            out << "void";
        }

        out << " "
            << method->name()
            << "("
            << Method::GetJavaArgSignature(method->args());

        if (needsCallback) {
            if (!method->args().empty()) {
                out << ", ";
            }

            out << method->name()
                << "Callback cb";
        }

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

        out << "android.os.HwParcel request = new android.os.HwParcel();\n";
        out << "request.writeInterfaceToken("
            << superInterface->fullJavaName()
            << ".kInterfaceName);\n";

        for (const auto &arg : method->args()) {
            emitJavaReaderWriter(
                    out,
                    "request",
                    arg,
                    false /* isReader */);
        }

        out << "\nandroid.os.HwParcel reply = new android.os.HwParcel();\n"
            << "mRemote.transact("
            << method->getSerialId()
            << " /* "
            << method->name()
            << " */, request, reply, ";

        if (method->isOneway()) {
            out << "android.os.IHwBinder.FLAG_ONEWAY";
        } else {
            out << "0 /* flags */";
        }

        out << ");\n";

        if (!method->isOneway()) {
            out << "reply.verifySuccess();\n";
        } else {
            CHECK(!returnsValue);
        }

        out << "request.releaseTemporaryStorage();\n";

        if (returnsValue) {
            out << "\n";

            for (const auto &arg : method->results()) {
                emitJavaReaderWriter(
                        out,
                        "reply",
                        arg,
                        true /* isReader */);
            }

            if (needsCallback) {
                out << "cb.onValues(";

                bool firstField = true;
                for (const auto &arg : method->results()) {
                    if (!firstField) {
                        out << ", ";
                    }

                    out << arg->name();
                    firstField = false;
                }

                out << ");\n";
            } else {
                const std::string returnName = method->results()[0]->name();
                out << "return " << returnName << ";\n";
            }
        }

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

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

    ////////////////////////////////////////////////////////////////////////////

    out << "\npublic static abstract class Stub extends android.os.HwBinder "
        << "implements "
        << ifaceName << " {\n";

    out.indent();

    out << "public android.os.IHwBinder asBinder() {\n";
    out.indent();
    out << "return this;\n";
    out.unindent();
    out << "}\n\n";

    // b/32383557 this is a hack. We need to change this if we have more reserved methods.
    for (Method *method : iface->hidlReservedMethods()) {
        out << "public final "
            << method->results()[0]->type().getJavaType()
            << " "
            << method->name()
            << "() {\n";
        out.indent();
        method->javaImpl(out);
        out.unindent();
        out << "\n}\n\n";
    }

    out << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
    out.indent();
    // XXX what about potential superClasses?
    out << "if (kInterfaceName.equals(descriptor)) {\n";
    out.indent();
    out << "return this;\n";
    out.unindent();
    out << "}\n";
    out << "return null;\n";
    out.unindent();
    out << "}\n\n";

    out << "public void registerAsService(String serviceName) {\n";
    out.indent();

    out << "registerService(interfaceChain(), serviceName);\n";

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

    out << "public void onTransact("
        << "int code, android.os.HwParcel request, final android.os.HwParcel reply, "
        << "int flags) {\n";

    out.indent();

    out << "switch (code) {\n";

    out.indent();

    for (const auto &tuple : iface->allMethodsFromRoot()) {
        const Method *method = tuple.method();
        const Interface *superInterface = tuple.interface();
        const bool returnsValue = !method->results().empty();
        const bool needsCallback = method->results().size() > 1;

        out << "case "
            << method->getSerialId()
            << " /* "
            << method->name()
            << " */:\n{\n";

        out.indent();

        out << "request.enforceInterface("
            << superInterface->fullJavaName()
            << ".kInterfaceName);\n\n";

        for (const auto &arg : method->args()) {
            emitJavaReaderWriter(
                    out,
                    "request",
                    arg,
                    true /* isReader */);
        }

        if (!needsCallback && returnsValue) {
            const TypedVar *returnArg = method->results()[0];

            out << returnArg->type().getJavaType()
                << " "
                << returnArg->name()
                << " = ";
        }

        out << method->name()
            << "(";

        bool firstField = true;
        for (const auto &arg : method->args()) {
            if (!firstField) {
                out << ", ";
            }

            out << arg->name();

            firstField = false;
        }

        if (needsCallback) {
            if (!firstField) {
                out << ", ";
            }

            out << "new " << method->name() << "Callback() {\n";
            out.indent();

            out << "@Override\n"
                << "public void onValues("
                << Method::GetJavaArgSignature(method->results())
                << ") {\n";

            out.indent();
            out << "reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";

            for (const auto &arg : method->results()) {
                emitJavaReaderWriter(
                        out,
                        "reply",
                        arg,
                        false /* isReader */);
            }

            out << "reply.send();\n"
                      << "}}";

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

        out << ");\n";

        if (!needsCallback) {
            out << "reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";

            if (returnsValue) {
                const TypedVar *returnArg = method->results()[0];

                emitJavaReaderWriter(
                        out,
                        "reply",
                        returnArg,
                        false /* isReader */);
            }

            out << "reply.send();\n";
        }

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

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

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

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

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

    return OK;
}

status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
    return mRootScope->emitJavaTypeDeclarations(out, false /* atTopLevel */);
}

}  // namespace android

