/*
 * Copyright (C) 2017 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 "EnumType.h"
#include "HidlTypeAssertion.h"
#include "Interface.h"
#include "Method.h"
#include "Reference.h"
#include "ScalarType.h"
#include "Scope.h"

#include <android-base/logging.h>
#include <hidl-util/Formatter.h>
#include <hidl-util/StringHelper.h>
#include <algorithm>
#include <string>
#include <vector>

namespace android {

void AST::generateCppAdapterHeader(Formatter& out) const {
    const std::string klassName = AST::isInterface() ? getInterface()->getAdapterName() : "Atypes";
    const std::string guard = makeHeaderGuard(klassName, true /* indicateGenerated */);

    out << "#ifndef " << guard << "\n";
    out << "#define " << guard << "\n\n";

    if (AST::isInterface()) {
        generateCppPackageInclude(out, mPackage, getInterface()->localName());

        enterLeaveNamespace(out, true /* enter */);
        out.endl();

        const std::string mockName = getInterface()->fqName().cppName();

        out << "class " << klassName << " : public " << mockName << " ";
        out.block([&] {
            out << "public:\n";
            out << "typedef " << mockName << " Pure;\n";

            out << klassName << "(::android::sp<" << mockName << "> impl);\n";

            generateMethods(out, [&](const Method* method, const Interface* /* interface */) {
                if (method->isHidlReserved()) {
                    return;
                }

                out << "virtual ";
                method->generateCppSignature(out);
                out << " override;\n";
            });
            out << "private:\n";
            out << "::android::sp<" << mockName << "> mImpl;\n";

        }) << ";\n\n";

        enterLeaveNamespace(out, false /* enter */);
    } else {
        out << "// no adapters for types.hal\n";
    }

    out << "#endif // " << guard << "\n";
}

void AST::generateCppAdapterSource(Formatter& out) const {
    const std::string klassName = AST::isInterface() ? getInterface()->getAdapterName() : "Atypes";

    generateCppPackageInclude(out, mPackage, klassName);

    if (AST::isInterface()) {
        out << "#include <hidladapter/HidlBinderAdapter.h>\n";
        generateCppPackageInclude(out, mPackage, getInterface()->localName());

        std::set<FQName> allImportedNames;
        getAllImportedNames(&allImportedNames);
        for (const auto& item : allImportedNames) {
            if (item.name() == "types") {
                continue;
            }
            generateCppPackageInclude(out, item, item.getInterfaceAdapterName());
        }

        out.endl();

        enterLeaveNamespace(out, true /* enter */);
        out.endl();

        const std::string mockName = getInterface()->fqName().cppName();

        out << klassName << "::" << klassName << "(::android::sp<" << mockName
            << "> impl) : mImpl(impl) {}";

        generateMethods(out, [&](const Method* method, const Interface* /* interface */) {
            generateAdapterMethod(out, method);
        });

        enterLeaveNamespace(out, false /* enter */);
        out.endl();
    } else {
        out << "// no adapters for types.hal\n";
    }
}

void AST::generateAdapterMethod(Formatter& out, const Method* method) const {
    if (method->isHidlReserved()) {
        return;
    }

    const auto adapt = [](Formatter& out, const std::string& var, const Type* type) {
        if (!type->isInterface()) {
            out << var;
            return;
        }

        // TODO(b/66900959): if we are creating the adapter for a 1.1 IFoo
        // and we are using a method that takes/returns a 1.0 Callback, but
        // there exists a 1.1 Callback (or other subclass that is depended
        // on by this module), then wrap with the adapter subclass adapter
        // IFF that callback is a subclass. However, if the callback
        // is 1.0 ICallback, then wrap with a 1.0 adapter.

        const Interface* interface = static_cast<const Interface*>(type);
        out << "static_cast<::android::sp<" << interface->fqName().cppName() << ">>("
            << interface->fqName().cppName() << "::castFrom("
            << "::android::hardware::details::adaptWithDefault("
            << "static_cast<::android::sp<" << interface->fqName().cppName() << ">>(" << var
            << "), [&] { return new " << interface->fqName().getInterfaceAdapterFqName().cppName()
            << "(" << var << "); })))";
    };

    const std::string klassName = getInterface()->getAdapterName();

    method->generateCppSignature(out, klassName);
    out.block([&] {
         bool hasCallback = !method->canElideCallback() && !method->results().empty();

         if (hasCallback) {
             out << method->name() << "_cb _hidl_cb_wrapped = [&](";
             method->emitCppResultSignature(out);
             out << ") ";
             out.block([&] {
                 out << "return _hidl_cb(\n";
                 out.indent([&]() {
                     out.join(method->results().begin(), method->results().end(), ",\n",
                              [&](auto arg) { adapt(out, arg->name(), arg->get()); });
                 });
                 out << ");\n";
             });
             out << ";\n";
         }

         out << "auto _hidl_out = mImpl->" << method->name() << "(\n";
         out.indent([&]() {
             out.join(method->args().begin(), method->args().end(), ",\n",
                      [&](auto arg) { adapt(out, arg->name(), arg->get()); });
             if (hasCallback) {
                 if (!method->args().empty()) {
                     out << ",\n";
                 }
                 out << "_hidl_cb_wrapped";
             }
         });
         out << ");\n";

         const auto elidedCallback = method->canElideCallback();
         if (elidedCallback) {
             out.sIf("!_hidl_out.isOkUnchecked()", [&] { out << "return _hidl_out;\n"; });
             out << "return ";
             adapt(out, "_hidl_out", elidedCallback->get());
             out << ";\n";
         } else {
             out << "return _hidl_out;\n";
         }
     }).endl();
}

}  // namespace android
