/*
 * 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 "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.inPackage("android.hardware.graphics.common") ||
           fqName.inPackage("android.hardware.graphics.mapper") ||
           fqName.string() == "android.hardware.renderscript@1.0" ||
           fqName.string() == "android.hidl.memory.token@1.0" ||
           fqName.string() == "android.hidl.memory@1.0" ||
           fqName.string() == "android.hidl.safe_union@1.0";
}

bool isCoreAndroidPackage(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 == nullptr) {
            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 isCoreAndroid = isCoreAndroidPackage(packageFQName);

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

    // Currently, all platform-provided interfaces are in the VNDK, so if it isn't in the VNDK, it
    // is device specific and so should be put in the product partition.
    bool isProduct = !isCoreAndroid;

    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 (isVndk) {
            out << "vndk: ";
            out.block([&]() {
                out << "enabled: true,\n";
                if (isVndkSp) {
                    out << "support_system_process: true,\n";
                }
            }) << ",\n";
        }
        if (isProduct) {
            out << "product_specific: true,\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 == nullptr) {
            fprintf(stderr,
                    "ERROR: Could not parse %s. Aborting.\n",
                    fqName.string().c_str());

            return UNKNOWN_ERROR;
        }

        ast->getImportedPackages(&importedPackages);
    }

    out << "// FIXME: your file license if you have one\n\n";
    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 == nullptr) {
                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 == nullptr) {
        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;
}

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

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

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

    const Interface* interface = ast->getInterface();
    if (interface == nullptr) {
        fprintf(stderr, "ERROR: Function count requires interface: %s.\n", fqName.string().c_str());
        return UNKNOWN_ERROR;
    }

    // This is wrong for android.hidl.base@1.0::IBase, but in that case, it doesn't matter.
    // This is just the number of APIs that are added.
    out << fqName.string() << " " << interface->userDefinedMethods().size() << "\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,
            },
        }
    },
    {
        "function-count",
        "Prints the total number of functions added by the package or interface.",
        OutputMode::NOT_NEEDED,
        Coordinator::Location::STANDARD_OUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::generateForInterfaces,
                nullptr /* file name for fqName */,
                generateFunctionCount,
            },
        }
    },
    {
        "dependencies",
        "Prints all depended types.",
        OutputMode::NOT_NEEDED,
        Coordinator::Location::STANDARD_OUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                nullptr /* file name for fqName */,
                astGenerationFunction(&AST::generateDependencies),
            },
        },
    },
};
// 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>)+ [-R] [-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: Do not add default package roots if not specified in -r.\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;
    bool suppressDefaultPackagePaths = false;

    int res;
    while ((res = getopt(argc, argv, "hp:o:O:r:L:vd:R")) >= 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 'R': {
                suppressDefaultPackagePaths = true;
                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);

    if (!suppressDefaultPackagePaths) {
        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) {
        const char* arg = argv[i];

        FQName fqName;
        if (!FQName::parse(arg, &fqName)) {
            fprintf(stderr, "ERROR: Invalid fully-qualified name as argument: %s.\n", arg);
            exit(1);
        }

        if (coordinator.getPackageInterfaceFiles(fqName, nullptr /*fileNames*/) != OK) {
            fprintf(stderr, "ERROR: Could not get sources for %s.\n", arg);
            exit(1);
        }

        // 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;
}
