/*
 * 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 "EnumType.h"
#include "Interface.h"
#include "Method.h"
#include "ScalarType.h"
#include "Scope.h"

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

namespace android {

status_t AST::generateCppImpl(const std::string &outputPath) const {
    status_t err = generateStubImplHeader(outputPath);

    if (err == OK) {
        err = generateStubImplSource(outputPath);
    }

    return err;
}

void AST::generateFetchSymbol(Formatter &out, const std::string& ifaceName) const {
    out << "HIDL_FETCH_" << ifaceName;
}

status_t AST::generateStubImplMethod(Formatter &out,
                                     const std::string &className,
                                     const Method *method,
                                     bool specifyNamespaces) const {

    method->generateCppSignature(out, className, specifyNamespaces);

    out << " {\n";

    out.indent();
    out << "// TODO implement\n";

    const TypedVar *elidedReturn = method->canElideCallback();

    if (elidedReturn == nullptr) {
        out << "return Void();\n";
    } else {
        std::string extra;
        out << "return "
            << elidedReturn->type().getCppResultType(&extra)
            << " {};\n";
    }

    out.unindent();

    out << "}\n\n";

    return OK;
}

status_t AST::generateStubImplDeclaration(Formatter &out,
                                          const std::string &className,
                                          const Method *method,
                                          bool specifyNamespaces) const {

    method->generateCppSignature(out,
                                 className,
                                 specifyNamespaces);
    out << " override;\n";

    return OK;
}

status_t AST::generateStubImplHeader(const std::string &outputPath) const {
    std::string ifaceName;
    if (!AST::isInterface(&ifaceName)) {
        // types.hal does not get a stub header.
        return OK;
    }

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

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

    std::string path = outputPath;
    path.append(baseName);
    path.append(".h");

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

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

    Formatter out(file);

    const std::string guard = makeHeaderGuard(baseName);

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

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

    out << "#include <";
    for (const auto &component : packageComponents) {
        out << component << "/";
    }
    out << "I" << baseName << ".h>\n";

    out << "#include <hidl/Status.h>\n\n";
    out << "#include <hidl/MQDescriptor.h>\n";

    enterLeaveNamespace(out, true /* enter */);
    out << "namespace implementation {\n\n";

    // this is namespace aware code and doesn't require post-processing
    out.setNamespace("");

    const Interface *ancestor = iface;
    std::vector<const Interface *> chain;
    while (ancestor != NULL) {
        chain.push_back(ancestor);
        ancestor = ancestor->superType();
    }

    std::set<const FQName> usedTypes{};

    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
        const Interface *superInterface = *it;

        superInterface->addNamedTypesToSet(usedTypes);

        for (const auto &method : superInterface->methods()) {
            for(const auto & arg : method->args()) {
                arg->type().addNamedTypesToSet(usedTypes);
            }
            for(const auto & results : method->results()) {
                results->type().addNamedTypesToSet(usedTypes);
            }
        }
    }

    std::set<const FQName> topLevelTypes{};

    for (const auto &name : usedTypes) {
        topLevelTypes.insert(name.getTopLevelType());
    }

    for (const FQName &name : topLevelTypes) {
        out << "using " << name.cppName() << ";\n";
    }

    out << "using ::android::hardware::Return;\n";
    out << "using ::android::hardware::Void;\n";
    out << "using ::android::hardware::hidl_vec;\n";
    out << "using ::android::hardware::hidl_string;\n";
    out << "using ::android::sp;\n";

    out << "\n";

    out << "struct "
        << baseName
        << " : public "
        << ifaceName
        << " {\n";

    out.indent();

    status_t err = generateMethods(out,
                                   "", /* class name */
                                   MethodLocation::IMPL_HEADER,
                                   false /* specify namespaces */);

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

    out.unindent();

    out << "};\n\n";

    out << "extern \"C\" "
        << ifaceName
        << "* ";
    generateFetchSymbol(out, ifaceName);
    out << "(const char* name);\n\n";

    out << "}  // namespace implementation\n";
    enterLeaveNamespace(out, false /* leave */);

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

    return OK;
}

status_t AST::generateStubImplSource(const std::string &outputPath) const {
    std::string ifaceName;
    if (!AST::isInterface(&ifaceName)) {
        // types.hal does not get a stub header.
        return OK;
    }

    const Interface *iface = mRootScope->getInterface();
    const std::string baseName = iface->getBaseName();

    std::string path = outputPath;
    path.append(baseName);
    path.append(".cpp");

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

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

    Formatter out(file);

    out << "#include \"" << baseName << ".h\"\n\n";

    enterLeaveNamespace(out, true /* enter */);
    out << "namespace implementation {\n\n";

    // this is namespace aware code and doesn't require post-processing
    out.setNamespace("");

    generateMethods(out,
                    baseName,
                    MethodLocation::IMPL_SOURCE,
                    false /* specify namespaces */);


    out << ifaceName
        << "* ";
    generateFetchSymbol(out, ifaceName);
    out << "(const char* /* name */) {\n";
    out.indent();
    out << "return new " << baseName << "();\n";
    out.unindent();
    out << "}\n\n";

    out << "} // namespace implementation\n";
    enterLeaveNamespace(out, false /* leave */);

    return OK;
}

}  // namespace android
