/*
 * 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) {
        std::string extra;
        out << arg->type().getJavaType(&extra)
            << extra
            << " "
            << 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";

        out << "import android.os.HwBlob;\n";
        out << "import android.os.HwParcel;\n\n";

        out << "import java.util.Arrays;\n";
        out << "import java.util.ArrayList;\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";

    out << "import android.os.IHwBinder;\n";
    out << "import android.os.IHwInterface;\n";
    out << "import android.os.HwBinder;\n";
    out << "import android.os.HwBlob;\n";
    out << "import android.os.HwParcel;\n\n";

    out << "import java.util.Arrays;\n";
    out << "import java.util.ArrayList;\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 << "IHwInterface";
    }

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

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

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

    out.indent();

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

    out << "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 IHwBinder asBinder();\n\n";

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

    out.indent();

    out << "return "
        << ifaceName
        << ".asInterface(HwBinder.getService(serviceName, "
        << mPackage.getPackageMajorVersion()
        << ", "
        << mPackage.getPackageMinorVersion()
        << "));\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) {
            std::string extra;
            out << method->results()[0]->type().getJavaType(&extra)
                << extra;
        } 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 IHwBinder mRemote;\n\n";
    out << "public Proxy(IHwBinder remote) {\n";
    out.indent();
    out << "mRemote = remote;\n";
    out.unindent();
    out << "}\n\n";

    out << "public 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) {
            std::string extra;
            out << method->results()[0]->type().getJavaType(&extra)
                << extra;
        } 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 << "HwParcel request = new HwParcel();\n";
        out << "request.writeInterfaceToken("
            << superInterface->fullJavaName()
            << ".kInterfaceName);\n";

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

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

        if (method->isOneway()) {
            out << "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 HwBinder "
        << "implements "
        << ifaceName << " {\n";

    out.indent();

    out << "public 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()) {
        std::string extra;
        out << "public final "
            << method->results()[0]->type().getJavaType(&extra)
            << extra
            << " "
            << method->name()
            << "() {\n";
        out.indent();
        method->javaImpl(out);
        out.unindent();
        out << "\n}\n\n";
    }

    out << "public 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(serviceName, "
        << mPackage.getPackageMajorVersion()
        << ", "
        << mPackage.getPackageMinorVersion()
        << ");\n";

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

    out << "public void onTransact("
        << "int code, HwParcel request, final 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];
            std::string extra;

            out << returnArg->type().getJavaType(&extra)
                << extra
                << " "
                << 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(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(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

