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

#include <android-base/logging.h>
#include <hidl-hash/Hash.h>
#include <hidl-util/FQName.h>
#include <hidl-util/Formatter.h>
#include <hidl-util/StringHelper.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>
#include <set>
#include <string>
#include <vector>

using namespace android;

enum class OutputMode {
    NEEDS_DIR,   // -o output option expects a directory
    NEEDS_FILE,  // -o output option expects a file
    NEEDS_SRC,   // for changes inside the source tree itself
    NOT_NEEDED   // does not create files
};

enum class GenerationGranularity {
    PER_PACKAGE,  // Files generated for each package
    PER_FILE,     // Files generated for each hal file
    PER_TYPE,     // Files generated for each hal file + each type in HAL files
};

// Represents a file that is generated by an -L option for an FQName
struct FileGenerator {
    using ShouldGenerateFunction = std::function<bool(const FQName& fqName)>;
    using FileNameForFQName = std::function<std::string(const FQName& fqName)>;
    using GenerationFunction = std::function<status_t(Formatter& out, const FQName& fqName,
                                                      const Coordinator* coordinator)>;

    ShouldGenerateFunction mShouldGenerateForFqName;  // If generate function applies to this target
    FileNameForFQName mFileNameForFqName;             // Target -> filename
    GenerationFunction mGenerationFunction;           // Function to generate output for file

    std::string getFileName(const FQName& fqName) const {
        return mFileNameForFqName ? mFileNameForFqName(fqName) : "";
    }

    status_t getOutputFile(const FQName& fqName, const Coordinator* coordinator,
                           Coordinator::Location location, std::string* file) const {
        if (!mShouldGenerateForFqName(fqName)) {
            return OK;
        }

        return coordinator->getFilepath(fqName, location, getFileName(fqName), file);
    }

    status_t appendOutputFiles(const FQName& fqName, const Coordinator* coordinator,
                               Coordinator::Location location,
                               std::vector<std::string>* outputFiles) const {
        if (location == Coordinator::Location::STANDARD_OUT) {
            return OK;
        }

        if (mShouldGenerateForFqName(fqName)) {
            std::string fileName;
            status_t err = getOutputFile(fqName, coordinator, location, &fileName);
            if (err != OK) return err;

            if (!fileName.empty()) {
                outputFiles->push_back(fileName);
            }
        }
        return OK;
    }

    status_t generate(const FQName& fqName, const Coordinator* coordinator,
                      Coordinator::Location location) const {
        CHECK(mShouldGenerateForFqName != nullptr);
        CHECK(mGenerationFunction != nullptr);

        if (!mShouldGenerateForFqName(fqName)) {
            return OK;
        }

        Formatter out = coordinator->getFormatter(fqName, location, getFileName(fqName));
        if (!out.isValid()) {
            return UNKNOWN_ERROR;
        }

        return mGenerationFunction(out, fqName, coordinator);
    }

    // Helper methods for filling out this struct
    static bool generateForTypes(const FQName& fqName) {
        const auto names = fqName.names();
        return names.size() > 0 && names[0] == "types";
    }
    static bool generateForInterfaces(const FQName& fqName) { return !generateForTypes(fqName); }
    static bool alwaysGenerate(const FQName&) { return true; }
};

// Represents a -L option, takes a fqName and generates files
struct OutputHandler {
    using ValidationFunction = std::function<bool(
        const FQName& fqName, const Coordinator* coordinator, const std::string& language)>;

    std::string mKey;                 // -L in Android.bp
    std::string mDescription;         // for display in help menu
    OutputMode mOutputMode;           // how this option interacts with -o
    Coordinator::Location mLocation;  // how to compute location relative to the output directory
    GenerationGranularity mGenerationGranularity;   // what to run generate function on
    ValidationFunction mValidate;                   // if a given fqName is allowed for this option
    std::vector<FileGenerator> mGenerateFunctions;  // run for each target at this granularity

    const std::string& name() const { return mKey; }
    const std::string& description() const { return mDescription; }

    status_t generate(const FQName& fqName, const Coordinator* coordinator) const;
    status_t validate(const FQName& fqName, const Coordinator* coordinator,
                      const std::string& language) const {
        return mValidate(fqName, coordinator, language);
    }

    status_t writeDepFile(const FQName& fqName, const Coordinator* coordinator) const;

   private:
    status_t appendTargets(const FQName& fqName, const Coordinator* coordinator,
                           std::vector<FQName>* targets) const;
    status_t appendOutputFiles(const FQName& fqName, const Coordinator* coordinator,
                               std::vector<std::string>* outputFiles) const;
};

// Helper method for GenerationGranularity::PER_TYPE
// IFoo -> IFoo, types.hal (containing Bar, Baz) -> types.Bar, types.Baz
static status_t appendPerTypeTargets(const FQName& fqName, const Coordinator* coordinator,
                                     std::vector<FQName>* exportedPackageInterfaces) {
    CHECK(fqName.isFullyQualified());
    if (fqName.name() != "types") {
        exportedPackageInterfaces->push_back(fqName);
        return OK;
    }

    AST* typesAST = coordinator->parse(fqName);
    if (typesAST == nullptr) {
        fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());
        return UNKNOWN_ERROR;
    }

    std::vector<NamedType*> rootTypes = typesAST->getRootScope()->getSubTypes();
    for (const NamedType* rootType : rootTypes) {
        if (rootType->isTypeDef()) continue;

        FQName rootTypeName(fqName.package(), fqName.version(), "types." + rootType->localName());
        exportedPackageInterfaces->push_back(rootTypeName);
    }
    return OK;
}

status_t OutputHandler::appendTargets(const FQName& fqName, const Coordinator* coordinator,
                                      std::vector<FQName>* targets) const {
    switch (mGenerationGranularity) {
        case GenerationGranularity::PER_PACKAGE: {
            targets->push_back(fqName.getPackageAndVersion());
        } break;
        case GenerationGranularity::PER_FILE: {
            if (fqName.isFullyQualified()) {
                targets->push_back(fqName);
                break;
            }
            status_t err = coordinator->appendPackageInterfacesToVector(fqName, targets);
            if (err != OK) return err;
        } break;
        case GenerationGranularity::PER_TYPE: {
            if (fqName.isFullyQualified()) {
                status_t err = appendPerTypeTargets(fqName, coordinator, targets);
                if (err != OK) return err;
            }

            std::vector<FQName> packageInterfaces;
            status_t err = coordinator->appendPackageInterfacesToVector(fqName, &packageInterfaces);
            if (err != OK) return err;
            for (const FQName& packageInterface : packageInterfaces) {
                err = appendPerTypeTargets(packageInterface, coordinator, targets);
                if (err != OK) return err;
            }
        } break;
        default:
            CHECK(!"Should be here");
    }

    return OK;
}

status_t OutputHandler::generate(const FQName& fqName, const Coordinator* coordinator) const {
    std::vector<FQName> targets;
    status_t err = appendTargets(fqName, coordinator, &targets);
    if (err != OK) return err;

    for (const FQName& fqName : targets) {
        for (const FileGenerator& file : mGenerateFunctions) {
            status_t err = file.generate(fqName, coordinator, mLocation);
            if (err != OK) return err;
        }
    }

    return OK;
}

status_t OutputHandler::appendOutputFiles(const FQName& fqName, const Coordinator* coordinator,
                                          std::vector<std::string>* outputFiles) const {
    std::vector<FQName> targets;
    status_t err = appendTargets(fqName, coordinator, &targets);
    if (err != OK) return err;

    for (const FQName& fqName : targets) {
        for (const FileGenerator& file : mGenerateFunctions) {
            err = file.appendOutputFiles(fqName, coordinator, mLocation, outputFiles);
            if (err != OK) return err;
        }
    }

    return OK;
}

status_t OutputHandler::writeDepFile(const FQName& fqName, const Coordinator* coordinator) const {
    std::vector<std::string> outputFiles;
    status_t err = appendOutputFiles(fqName, coordinator, &outputFiles);
    if (err != OK) return err;

    // No need for dep files
    if (outputFiles.empty()) {
        return OK;
    }

    // Depfiles in Android for genrules should be for the 'main file'. Because hidl-gen doesn't have
    // a main file for most targets, we are just outputting a depfile for one single file only.
    const std::string forFile = outputFiles[0];

    return coordinator->writeDepFile(forFile);
}

// Use an AST function as a OutputHandler GenerationFunction
static FileGenerator::GenerationFunction astGenerationFunction(void (AST::*generate)(Formatter&)
                                                                   const = nullptr) {
    return [generate](Formatter& out, const FQName& fqName,
                      const Coordinator* coordinator) -> status_t {
        AST* ast = coordinator->parse(fqName);
        if (ast == nullptr) {
            fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());
            return UNKNOWN_ERROR;
        }

        if (generate == nullptr) return OK;  // just parsing AST
        (ast->*generate)(out);

        return OK;
    };
}

// Common pattern: single file for package or standard out
static FileGenerator singleFileGenerator(
    const std::string& fileName, const FileGenerator::GenerationFunction& generationFunction) {
    return {
        FileGenerator::alwaysGenerate, [fileName](const FQName&) { return fileName; },
        generationFunction,
    };
}

static status_t generateJavaForPackage(Formatter& out, const FQName& fqName,
                                       const Coordinator* coordinator) {
    AST* ast;
    std::string limitToType;

    // Required for legacy -Lmakefile files
    if (fqName.name().find("types.") == 0) {
        limitToType = fqName.name().substr(strlen("types."));

        FQName typesName = fqName.getTypesForPackage();
        ast = coordinator->parse(typesName);
    } else {
        ast = coordinator->parse(fqName);
    }
    if (ast == nullptr) {
        fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());
        return UNKNOWN_ERROR;
    }
    ast->generateJava(out, limitToType);
    return OK;
};

static status_t dumpDefinedButUnreferencedTypeNames(const FQName& packageFQName,
                                                    const Coordinator* coordinator) {
    std::vector<FQName> packageInterfaces;
    status_t err = coordinator->appendPackageInterfacesToVector(packageFQName, &packageInterfaces);
    if (err != OK) return err;

    std::set<FQName> unreferencedDefinitions;
    std::set<FQName> unreferencedImports;
    err = coordinator->addUnreferencedTypes(packageInterfaces, &unreferencedDefinitions,
                                            &unreferencedImports);
    if (err != OK) return err;

    for (const auto& fqName : unreferencedDefinitions) {
        std::cerr
            << "VERBOSE: DEFINED-BUT-NOT-REFERENCED "
            << fqName.string()
            << std::endl;
    }

    for (const auto& fqName : unreferencedImports) {
        std::cerr
            << "VERBOSE: IMPORTED-BUT-NOT-REFERENCED "
            << fqName.string()
            << std::endl;
    }

    return OK;
}

static std::string makeLibraryName(const FQName &packageFQName) {
    return packageFQName.string();
}

static status_t isPackageJavaCompatible(const FQName& packageFQName, const Coordinator* coordinator,
                                        bool* compatible) {
    std::vector<FQName> todo;
    status_t err =
        coordinator->appendPackageInterfacesToVector(packageFQName, &todo);

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

    std::set<FQName> seen;
    for (const auto &iface : todo) {
        seen.insert(iface);
    }

    // Form the transitive closure of all imported interfaces (and types.hal-s)
    // If any one of them is not java compatible, this package isn't either.
    while (!todo.empty()) {
        const FQName fqName = todo.back();
        todo.pop_back();

        AST *ast = coordinator->parse(fqName);

        if (ast == nullptr) {
            return UNKNOWN_ERROR;
        }

        if (!ast->isJavaCompatible()) {
            *compatible = false;
            return OK;
        }

        std::set<FQName> importedPackages;
        ast->getImportedPackages(&importedPackages);

        for (const auto &package : importedPackages) {
            std::vector<FQName> packageInterfaces;
            status_t err = coordinator->appendPackageInterfacesToVector(
                    package, &packageInterfaces);

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

            for (const auto &iface : packageInterfaces) {
                if (seen.find(iface) != seen.end()) {
                    continue;
                }

                todo.push_back(iface);
                seen.insert(iface);
            }
        }
    }

    *compatible = true;
    return OK;
}

static bool packageNeedsJavaCode(
        const std::vector<FQName> &packageInterfaces, AST *typesAST) {
    if (packageInterfaces.size() == 0) {
        return false;
    }

    // If there is more than just a types.hal file to this package we'll
    // definitely need to generate Java code.
    if (packageInterfaces.size() > 1
            || packageInterfaces[0].name() != "types") {
        return true;
    }

    CHECK(typesAST != nullptr);

    // We'll have to generate Java code if types.hal contains any non-typedef
    // type declarations.

    Scope* rootScope = typesAST->getRootScope();
    std::vector<NamedType *> subTypes = rootScope->getSubTypes();

    for (const auto &subType : subTypes) {
        if (!subType->isTypeDef()) {
            return true;
        }
    }

    return false;
}

bool validateIsPackage(const FQName& fqName, const Coordinator*,
                       const std::string& /* language */) {
    if (fqName.package().empty()) {
        fprintf(stderr, "ERROR: Expecting package name\n");
        return false;
    }

    if (fqName.version().empty()) {
        fprintf(stderr, "ERROR: Expecting package version\n");
        return false;
    }

    if (!fqName.name().empty()) {
        fprintf(stderr,
                "ERROR: Expecting only package name and version.\n");
        return false;
    }

    return true;
}

bool isHidlTransportPackage(const FQName& fqName) {
    return fqName.package() == gIBaseFqName.package() ||
           fqName.package() == gIManagerFqName.package();
}

bool isSystemProcessSupportedPackage(const FQName& fqName) {
    // Technically, so is hidl IBase + IServiceManager, but
    // these are part of libhidltransport.
    return fqName.string() == "android.hardware.graphics.common@1.0" ||
           fqName.string() == "android.hardware.graphics.common@1.1" ||
           fqName.string() == "android.hardware.graphics.mapper@2.0" ||
           fqName.string() == "android.hardware.graphics.mapper@2.1" ||
           fqName.string() == "android.hardware.renderscript@1.0" ||
           fqName.string() == "android.hidl.memory.token@1.0" ||
           fqName.string() == "android.hidl.memory@1.0";
}

bool isSystemPackage(const FQName &package) {
    return package.inPackage("android.hidl") ||
           package.inPackage("android.system") ||
           package.inPackage("android.frameworks") ||
           package.inPackage("android.hardware");
}

// TODO(b/69862859): remove special case
status_t isTestPackage(const FQName& fqName, const Coordinator* coordinator, bool* isTestPackage) {
    const auto fileExists = [](const std::string& file) {
        struct stat buf;
        return stat(file.c_str(), &buf) == 0;
    };

    std::string path;
    status_t err = coordinator->getFilepath(fqName, Coordinator::Location::PACKAGE_ROOT,
                                            ".hidl_for_test", &path);
    if (err != OK) return err;

    const bool exists = fileExists(path);

    if (exists) {
        coordinator->onFileAccess(path, "r");
    }

    *isTestPackage = exists;
    return OK;
}

static status_t generateAdapterMainSource(Formatter& out, const FQName& packageFQName,
                                          const Coordinator* coordinator) {
    std::vector<FQName> packageInterfaces;
    status_t err =
        coordinator->appendPackageInterfacesToVector(packageFQName,
                                                     &packageInterfaces);
    if (err != OK) {
        return err;
    }

    out << "#include <hidladapter/HidlBinderAdapter.h>\n";

    for (auto &interface : packageInterfaces) {
        if (interface.name() == "types") {
            continue;
        }
        AST::generateCppPackageInclude(out, interface, interface.getInterfaceAdapterName());
    }

    out << "int main(int argc, char** argv) ";
    out.block([&] {
        out << "return ::android::hardware::adapterMain<\n";
        out.indent();
        for (auto &interface : packageInterfaces) {
            if (interface.name() == "types") {
                continue;
            }
            out << interface.getInterfaceAdapterFqName().cppName();

            if (&interface != &packageInterfaces.back()) {
                out << ",\n";
            }
        }
        out << ">(\"" << packageFQName.string() << "\", argc, argv);\n";
        out.unindent();
    }).endl();
    return OK;
}

static status_t generateAndroidBpForPackage(Formatter& out, const FQName& packageFQName,
                                            const Coordinator* coordinator) {
    CHECK(!packageFQName.isFullyQualified() && packageFQName.name().empty());

    std::vector<FQName> packageInterfaces;

    status_t err = coordinator->appendPackageInterfacesToVector(packageFQName, &packageInterfaces);

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

    std::set<FQName> importedPackagesHierarchy;
    std::vector<const Type *> exportedTypes;
    AST* typesAST = nullptr;

    for (const auto& fqName : packageInterfaces) {
        AST* ast = coordinator->parse(fqName);

        if (ast == NULL) {
            fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());

            return UNKNOWN_ERROR;
        }

        if (fqName.name() == "types") {
            typesAST = ast;
        }

        ast->getImportedPackagesHierarchy(&importedPackagesHierarchy);
        ast->appendToExportedTypesVector(&exportedTypes);
    }

    bool needsJavaCode = packageNeedsJavaCode(packageInterfaces, typesAST);

    bool genJavaConstants = needsJavaCode && !exportedTypes.empty();

    bool isJavaCompatible;
    err = isPackageJavaCompatible(packageFQName, coordinator, &isJavaCompatible);
    if (err != OK) return err;
    bool genJavaLibrary = needsJavaCode && isJavaCompatible;

    bool generateForTest;
    err = isTestPackage(packageFQName, coordinator, &generateForTest);
    if (err != OK) return err;

    bool isVndk = !generateForTest && isSystemPackage(packageFQName);
    bool isVndkSp = isVndk && isSystemProcessSupportedPackage(packageFQName);

    std::string packageRoot;
    err = coordinator->getPackageRoot(packageFQName, &packageRoot);
    if (err != OK) return err;

    out << "// This file is autogenerated by hidl-gen -Landroidbp.\n\n";

    out << "hidl_interface ";
    out.block([&] {
        out << "name: \"" << makeLibraryName(packageFQName) << "\",\n";
        if (!coordinator->getOwner().empty()) {
            out << "owner: \"" << coordinator->getOwner() << "\",\n";
        }
        out << "root: \"" << packageRoot << "\",\n";
        if (isHidlTransportPackage(packageFQName)) {
            out << "core_interface: true,\n";
        }
        if (isVndk) {
            out << "vndk: ";
            out.block([&]() {
                out << "enabled: true,\n";
                if (isVndkSp) {
                    out << "support_system_process: true,\n";
                }
            }) << ",\n";
        }
        (out << "srcs: [\n").indent([&] {
           for (const auto& fqName : packageInterfaces) {
               out << "\"" << fqName.name() << ".hal\",\n";
           }
        }) << "],\n";
        if (!importedPackagesHierarchy.empty()) {
            (out << "interfaces: [\n").indent([&] {
               for (const auto& fqName : importedPackagesHierarchy) {
                   out << "\"" << fqName.string() << "\",\n";
               }
            }) << "],\n";
        }
        if (typesAST != nullptr) {
            (out << "types: [\n").indent([&] {
                std::vector<NamedType *> subTypes = typesAST->getRootScope()->getSubTypes();
                std::sort(
                        subTypes.begin(),
                        subTypes.end(),
                        [](const NamedType *a, const NamedType *b) -> bool {
                            return a->fqName() < b->fqName();
                        });

                for (const auto &type : subTypes) {
                    if (type->isTypeDef()) {
                        continue;
                    }

                    out << "\"" << type->localName() << "\",\n";
                }
            }) << "],\n";
        }
        // Explicity call this out for developers.
        out << "gen_java: " << (genJavaLibrary ? "true" : "false") << ",\n";
        if (genJavaConstants) {
            out << "gen_java_constants: true,\n";
        }
   }).endl().endl();

    return OK;
}

static status_t generateAndroidBpImplForPackage(Formatter& out, const FQName& packageFQName,
                                                const Coordinator* coordinator) {
    const std::string libraryName = makeLibraryName(packageFQName) + "-impl";

    std::vector<FQName> packageInterfaces;

    status_t err =
        coordinator->appendPackageInterfacesToVector(packageFQName,
                                                     &packageInterfaces);

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

    std::set<FQName> importedPackages;

    for (const auto &fqName : packageInterfaces) {
        AST *ast = coordinator->parse(fqName);

        if (ast == NULL) {
            fprintf(stderr,
                    "ERROR: Could not parse %s. Aborting.\n",
                    fqName.string().c_str());

            return UNKNOWN_ERROR;
        }

        ast->getImportedPackages(&importedPackages);
    }

    out << "cc_library_shared {\n";
    out.indent([&] {
        out << "// FIXME: this should only be -impl for a passthrough hal.\n"
            << "// In most cases, to convert this to a binderized implementation, you should:\n"
            << "// - change '-impl' to '-service' here and make it a cc_binary instead of a\n"
            << "//   cc_library_shared.\n"
            << "// - add a *.rc file for this module.\n"
            << "// - delete HIDL_FETCH_I* functions.\n"
            << "// - call configureRpcThreadpool and registerAsService on the instance.\n"
            << "// You may also want to append '-impl/-service' with a specific identifier like\n"
            << "// '-vendor' or '-<hardware identifier>' etc to distinguish it.\n";
        out << "name: \"" << libraryName << "\",\n";
        if (!coordinator->getOwner().empty()) {
            out << "owner: \"" << coordinator->getOwner() << "\",\n";
        }
        out << "relative_install_path: \"hw\",\n";
        if (coordinator->getOwner().empty()) {
            out << "// FIXME: this should be 'vendor: true' for modules that will eventually be\n"
                   "// on AOSP.\n";
        }
        out << "proprietary: true,\n";
        out << "srcs: [\n";
        out.indent([&] {
            for (const auto &fqName : packageInterfaces) {
                if (fqName.name() == "types") {
                    continue;
                }
                out << "\"" << fqName.getInterfaceBaseName() << ".cpp\",\n";
            }
        });
        out << "],\n"
            << "shared_libs: [\n";
        out.indent([&] {
            out << "\"libhidlbase\",\n"
                << "\"libhidltransport\",\n"
                << "\"libutils\",\n"
                << "\"" << makeLibraryName(packageFQName) << "\",\n";

            for (const auto &importedPackage : importedPackages) {
                if (isHidlTransportPackage(importedPackage)) {
                    continue;
                }

                out << "\"" << makeLibraryName(importedPackage) << "\",\n";
            }
        });
        out << "],\n";
    });
    out << "}\n";

    return OK;
}

bool validateForSource(const FQName& fqName, const Coordinator* coordinator,
                       const std::string& language) {
    if (fqName.package().empty()) {
        fprintf(stderr, "ERROR: Expecting package name\n");
        return false;
    }

    if (fqName.version().empty()) {
        fprintf(stderr, "ERROR: Expecting package version\n");
        return false;
    }

    const std::string &name = fqName.name();
    if (!name.empty()) {
        if (name.find('.') == std::string::npos) {
            return true;
        }

        if (language != "java" || name.find("types.") != 0) {
            // When generating java sources for "types.hal", output can be
            // constrained to just one of the top-level types declared
            // by using the extended syntax
            // android.hardware.Foo@1.0::types.TopLevelTypeName.
            // In all other cases (different language, not 'types') the dot
            // notation in the name is illegal in this context.
            return false;
        }

        return true;
    }

    if (language == "java") {
        bool isJavaCompatible;
        status_t err = isPackageJavaCompatible(fqName, coordinator, &isJavaCompatible);
        if (err != OK) return false;

        if (!isJavaCompatible) {
            fprintf(stderr,
                    "ERROR: %s 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",
                    fqName.string().c_str());
            return false;
        }
    }

    return true;
}

FileGenerator::GenerationFunction generateExportHeaderForPackage(bool forJava) {
    return [forJava](Formatter& out, const FQName& packageFQName,
                     const Coordinator* coordinator) -> status_t {
        CHECK(!packageFQName.package().empty() && !packageFQName.version().empty() &&
              packageFQName.name().empty());

        std::vector<FQName> packageInterfaces;

        status_t err = coordinator->appendPackageInterfacesToVector(
                packageFQName, &packageInterfaces);

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

        std::vector<const Type *> exportedTypes;

        for (const auto &fqName : packageInterfaces) {
            AST *ast = coordinator->parse(fqName);

            if (ast == NULL) {
                fprintf(stderr,
                        "ERROR: Could not parse %s. Aborting.\n",
                        fqName.string().c_str());

                return UNKNOWN_ERROR;
            }

            ast->appendToExportedTypesVector(&exportedTypes);
        }

        if (exportedTypes.empty()) {
            return OK;
        }

        if (!out.isValid()) {
            return UNKNOWN_ERROR;
        }

        std::string packagePath;
        err = coordinator->getPackagePath(packageFQName, false /* relative */,
                                          false /* sanitized */, &packagePath);
        if (err != OK) return err;

        out << "// This file is autogenerated by hidl-gen. Do not edit manually.\n"
            << "// Source: " << packageFQName.string() << "\n"
            << "// Location: " << packagePath << "\n\n";

        std::string guard;
        if (forJava) {
            out << "package " << packageFQName.javaPackage() << ";\n\n";
            out << "public class Constants {\n";
            out.indent();
        } else {
            guard = "HIDL_GENERATED_";
            guard += StringHelper::Uppercase(packageFQName.tokenName());
            guard += "_";
            guard += "EXPORTED_CONSTANTS_H_";

            out << "#ifndef "
                << guard
                << "\n#define "
                << guard
                << "\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n";
        }

        for (const auto &type : exportedTypes) {
            type->emitExportedHeader(out, forJava);
        }

        if (forJava) {
            out.unindent();
            out << "}\n";
        } else {
            out << "#ifdef __cplusplus\n}\n#endif\n\n#endif  // "
                << guard
                << "\n";
        }

        return OK;
    };
}

static status_t generateHashOutput(Formatter& out, const FQName& fqName,
                                   const Coordinator* coordinator) {
    CHECK(fqName.isFullyQualified());

    AST* ast = coordinator->parse(fqName, {} /* parsed */,
                                  Coordinator::Enforce::NO_HASH /* enforcement */);

    if (ast == NULL) {
        fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());

        return UNKNOWN_ERROR;
    }

    out << Hash::getHash(ast->getFilename()).hexString() << " " << fqName.string() << "\n";

    return OK;
}

template <typename T>
std::vector<T> operator+(const std::vector<T>& lhs, const std::vector<T>& rhs) {
    std::vector<T> ret;
    ret.reserve(lhs.size() + rhs.size());
    ret.insert(ret.begin(), lhs.begin(), lhs.end());
    ret.insert(ret.end(), rhs.begin(), rhs.end());
    return ret;
}

// clang-format off
static const std::vector<FileGenerator> kCppHeaderFormats = {
    {
        FileGenerator::alwaysGenerate,
        [](const FQName& fqName) { return fqName.name() + ".h"; },
        astGenerationFunction(&AST::generateInterfaceHeader),
    },
    {
        FileGenerator::alwaysGenerate,
        [](const FQName& fqName) {
            return fqName.isInterfaceName() ? fqName.getInterfaceHwName() + ".h" : "hwtypes.h";
        },
        astGenerationFunction(&AST::generateHwBinderHeader),
    },
    {
        FileGenerator::generateForInterfaces,
        [](const FQName& fqName) { return fqName.getInterfaceStubName() + ".h"; },
        astGenerationFunction(&AST::generateStubHeader),
    },
    {
        FileGenerator::generateForInterfaces,
        [](const FQName& fqName) { return fqName.getInterfaceProxyName() + ".h"; },
        astGenerationFunction(&AST::generateProxyHeader),
    },
    {
        FileGenerator::generateForInterfaces,
        [](const FQName& fqName) { return fqName.getInterfacePassthroughName() + ".h"; },
        astGenerationFunction(&AST::generatePassthroughHeader),
    },
};

static const std::vector<FileGenerator> kCppSourceFormats = {
    {
        FileGenerator::alwaysGenerate,
        [](const FQName& fqName) {
            return fqName.isInterfaceName() ? fqName.getInterfaceBaseName() + "All.cpp" : "types.cpp";
        },
        astGenerationFunction(&AST::generateCppSource),
    },
};

static const std::vector<FileGenerator> kCppImplHeaderFormats = {
    {
        FileGenerator::generateForInterfaces,
        [](const FQName& fqName) { return fqName.getInterfaceBaseName() + ".h"; },
        astGenerationFunction(&AST::generateCppImplHeader),
    },
};

static const std::vector<FileGenerator> kCppImplSourceFormats = {
    {
        FileGenerator::generateForInterfaces,
        [](const FQName& fqName) { return fqName.getInterfaceBaseName() + ".cpp"; },
        astGenerationFunction(&AST::generateCppImplSource),
    },
};

static const std::vector<FileGenerator> kCppAdapterHeaderFormats = {
    {
        FileGenerator::alwaysGenerate,
        [](const FQName& fqName) {
            return fqName.isInterfaceName() ? fqName.getInterfaceAdapterName() + ".h" : "Atypes.h";
        },
        astGenerationFunction(&AST::generateCppAdapterHeader),
    },
};

static const std::vector<FileGenerator> kCppAdapterSourceFormats = {
    {
        FileGenerator::alwaysGenerate,
        [](const FQName& fqName) {
            return fqName.isInterfaceName() ? fqName.getInterfaceAdapterName() + ".cpp" : "Atypes.cpp";
        },
        astGenerationFunction(&AST::generateCppAdapterSource),
    },
};

static const std::vector<OutputHandler> kFormats = {
    {
        "check",
        "Parses the interface to see if valid but doesn't write any files.",
        OutputMode::NOT_NEEDED,
        Coordinator::Location::STANDARD_OUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                nullptr /* filename for fqname */,
                astGenerationFunction(),
            },
        },
    },
    {
        "c++",
        "(internal) (deprecated) Generates C++ interface files for talking to HIDL interfaces.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppHeaderFormats + kCppSourceFormats,
    },
    {
        "c++-headers",
        "(internal) Generates C++ headers for interface files for talking to HIDL interfaces.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppHeaderFormats,
    },
    {
        "c++-sources",
        "(internal) Generates C++ sources for interface files for talking to HIDL interfaces.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppSourceFormats,
    },
    {
        "export-header",
        "Generates a header file from @export enumerations to help maintain legacy code.",
        OutputMode::NEEDS_FILE,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_PACKAGE,
        validateIsPackage,
        {singleFileGenerator("", generateExportHeaderForPackage(false /* forJava */))}
    },
    {
        "c++-impl",
        "Generates boilerplate implementation of a hidl interface in C++ (for convenience).",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppImplHeaderFormats + kCppImplSourceFormats,
    },
    {
        "c++-impl-headers",
        "c++-impl but headers only",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppImplHeaderFormats,
    },
    {
        "c++-impl-sources",
        "c++-impl but sources only",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppImplSourceFormats,
    },
    {
        "c++-adapter",
        "Takes a x.(y+n) interface and mocks an x.y interface.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppAdapterHeaderFormats + kCppAdapterSourceFormats,
    },
    {
        "c++-adapter-headers",
        "c++-adapter but helper headers only",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppAdapterHeaderFormats,
    },
    {
        "c++-adapter-sources",
        "c++-adapter but helper sources only",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        kCppAdapterSourceFormats,
    },
    {
        "c++-adapter-main",
        "c++-adapter but the adapter binary source only",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_PACKAGE,
        validateIsPackage,
        {singleFileGenerator("main.cpp", generateAdapterMainSource)},
    },
    {
        "java",
        "(internal) Generates Java library for talking to HIDL interfaces in Java.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_SANITIZED,
        GenerationGranularity::PER_TYPE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                [](const FQName& fqName) {
                    return StringHelper::LTrim(fqName.name(), "types.") + ".java";
                },
                generateJavaForPackage,
            },
        }
    },
    {
        "java-constants",
        "(internal) Like export-header but for Java (always created by -Lmakefile if @export exists).",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_SANITIZED,
        GenerationGranularity::PER_PACKAGE,
        validateIsPackage,
        {singleFileGenerator("Constants.java", generateExportHeaderForPackage(true /* forJava */))}
    },
    {
        "vts",
        "(internal) Generates vts proto files for use in vtsd.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::GEN_OUTPUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                [](const FQName& fqName) {
                    return fqName.isInterfaceName() ? fqName.getInterfaceBaseName() + ".vts" : "types.vts";
                },
                astGenerationFunction(&AST::generateVts),
            },
        }
    },
    {
        "makefile",
        "(removed) Used to generate makefiles for -Ljava and -Ljava-constants.",
        OutputMode::NEEDS_SRC,
        Coordinator::Location::PACKAGE_ROOT,
        GenerationGranularity::PER_PACKAGE,
        [](const FQName &, const Coordinator*, const std::string &) {
           fprintf(stderr, "ERROR: makefile output is not supported. Use -Landroidbp for all build file generation.\n");
           return false;
        },
        {},
    },
    {
        "androidbp",
        "(internal) Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter.",
        OutputMode::NEEDS_SRC,
        Coordinator::Location::PACKAGE_ROOT,
        GenerationGranularity::PER_PACKAGE,
        validateIsPackage,
        {singleFileGenerator("Android.bp", generateAndroidBpForPackage)},
    },
    {
        "androidbp-impl",
        "Generates boilerplate bp files for implementation created with -Lc++-impl.",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_PACKAGE,
        validateIsPackage,
        {singleFileGenerator("Android.bp", generateAndroidBpImplForPackage)},
    },
    {
        "hash",
        "Prints hashes of interface in `current.txt` format to standard out.",
        OutputMode::NOT_NEEDED,
        Coordinator::Location::STANDARD_OUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                nullptr /* file name for fqName */,
                generateHashOutput,
            },
        }
    },
};
// clang-format on

static void usage(const char *me) {
    fprintf(stderr,
            "usage: %s [-p <root path>] -o <output path> -L <language> [-O <owner>] (-r <interface "
            "root>)+ [-v] [-d <depfile>] FQNAME...\n\n",
            me);

    fprintf(stderr,
            "Process FQNAME, PACKAGE(.SUBPACKAGE)*@[0-9]+.[0-9]+(::TYPE)?, to create output.\n\n");

    fprintf(stderr, "         -h: Prints this menu.\n");
    fprintf(stderr, "         -L <language>: The following options are available:\n");
    for (auto& e : kFormats) {
        fprintf(stderr, "            %-16s: %s\n", e.name().c_str(), e.description().c_str());
    }
    fprintf(stderr, "         -O <owner>: The owner of the module for -Landroidbp(-impl)?.\n");
    fprintf(stderr, "         -o <output path>: Location to output files.\n");
    fprintf(stderr, "         -p <root path>: Android build root, defaults to $ANDROID_BUILD_TOP or pwd.\n");
    fprintf(stderr, "         -r <package:path root>: E.g., android.hardware:hardware/interfaces.\n");
    fprintf(stderr, "         -v: verbose output.\n");
    fprintf(stderr, "         -d <depfile>: location of depfile to write to.\n");
}

// hidl is intentionally leaky. Turn off LeakSanitizer by default.
extern "C" const char *__asan_default_options() {
    return "detect_leaks=0";
}

int main(int argc, char **argv) {
    const char *me = argv[0];
    if (argc == 1) {
        usage(me);
        exit(1);
    }

    const OutputHandler* outputFormat = nullptr;
    Coordinator coordinator;
    std::string outputPath;

    int res;
    while ((res = getopt(argc, argv, "hp:o:O:r:L:vd:")) >= 0) {
        switch (res) {
            case 'p': {
                if (!coordinator.getRootPath().empty()) {
                    fprintf(stderr, "ERROR: -p <root path> can only be specified once.\n");
                    exit(1);
                }
                coordinator.setRootPath(optarg);
                break;
            }

            case 'v': {
                coordinator.setVerbose(true);
                break;
            }

            case 'd': {
                coordinator.setDepFile(optarg);
                break;
            }

            case 'o': {
                if (!outputPath.empty()) {
                    fprintf(stderr, "ERROR: -o <output path> can only be specified once.\n");
                    exit(1);
                }
                outputPath = optarg;
                break;
            }

            case 'O': {
                if (!coordinator.getOwner().empty()) {
                    fprintf(stderr, "ERROR: -O <owner> can only be specified once.\n");
                    exit(1);
                }
                coordinator.setOwner(optarg);
                break;
            }

            case 'r': {
                std::string val(optarg);
                auto index = val.find_first_of(':');
                if (index == std::string::npos) {
                    fprintf(stderr, "ERROR: -r option must contain ':': %s\n", val.c_str());
                    exit(1);
                }

                auto root = val.substr(0, index);
                auto path = val.substr(index + 1);

                std::string error;
                status_t err = coordinator.addPackagePath(root, path, &error);
                if (err != OK) {
                    fprintf(stderr, "%s\n", error.c_str());
                    exit(1);
                }

                break;
            }

            case 'L': {
                if (outputFormat != nullptr) {
                    fprintf(stderr,
                            "ERROR: only one -L option allowed. \"%s\" already specified.\n",
                            outputFormat->name().c_str());
                    exit(1);
                }
                for (auto& e : kFormats) {
                    if (e.name() == optarg) {
                        outputFormat = &e;
                        break;
                    }
                }
                if (outputFormat == nullptr) {
                    fprintf(stderr,
                            "ERROR: unrecognized -L option: \"%s\".\n",
                            optarg);
                    exit(1);
                }
                break;
            }

            case '?':
            case 'h':
            default: {
                usage(me);
                exit(1);
                break;
            }
        }
    }

    if (coordinator.getRootPath().empty()) {
        const char* ANDROID_BUILD_TOP = getenv("ANDROID_BUILD_TOP");
        if (ANDROID_BUILD_TOP != nullptr) {
            coordinator.setRootPath(ANDROID_BUILD_TOP);
        }
    }

    if (outputFormat == nullptr) {
        fprintf(stderr,
            "ERROR: no -L option provided.\n");
        exit(1);
    }

    argc -= optind;
    argv += optind;

    if (argc == 0) {
        fprintf(stderr, "ERROR: no fqname specified.\n");
        usage(me);
        exit(1);
    }

    // Valid options are now in argv[0] .. argv[argc - 1].

    switch (outputFormat->mOutputMode) {
        case OutputMode::NEEDS_DIR:
        case OutputMode::NEEDS_FILE: {
            if (outputPath.empty()) {
                usage(me);
                exit(1);
            }

            if (outputFormat->mOutputMode == OutputMode::NEEDS_DIR) {
                if (outputPath.back() != '/') {
                    outputPath += "/";
                }
            }
            break;
        }
        case OutputMode::NEEDS_SRC: {
            if (outputPath.empty()) {
                outputPath = coordinator.getRootPath();
            }
            if (outputPath.back() != '/') {
                outputPath += "/";
            }

            break;
        }

        default:
            outputPath.clear();  // Unused.
            break;
    }

    coordinator.setOutputPath(outputPath);

    coordinator.addDefaultPackagePath("android.hardware", "hardware/interfaces");
    coordinator.addDefaultPackagePath("android.hidl", "system/libhidl/transport");
    coordinator.addDefaultPackagePath("android.frameworks", "frameworks/hardware/interfaces");
    coordinator.addDefaultPackagePath("android.system", "system/hardware/interfaces");

    for (int i = 0; i < argc; ++i) {
        FQName fqName;
        if (!FQName::parse(argv[i], &fqName)) {
            fprintf(stderr, "ERROR: Invalid fully-qualified name as argument: %s.\n", argv[i]);
            exit(1);
        }

        // TODO(b/65200821): remove
        gCurrentCompileName = "_" + StringHelper::Uppercase(fqName.tokenName());

        // Dump extra verbose output
        if (coordinator.isVerbose()) {
            status_t err =
                dumpDefinedButUnreferencedTypeNames(fqName.getPackageAndVersion(), &coordinator);
            if (err != OK) return err;
        }

        if (!outputFormat->validate(fqName, &coordinator, outputFormat->name())) {
            fprintf(stderr,
                    "ERROR: output handler failed.\n");
            exit(1);
        }

        status_t err = outputFormat->generate(fqName, &coordinator);
        if (err != OK) exit(1);

        err = outputFormat->writeDepFile(fqName, &coordinator);
        if (err != OK) exit(1);
    }

    return 0;
}
