/*
 * 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 <sstream>
#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 GetFormatter = std::function<Formatter(void)>;
    using GenerationFunction =
            std::function<status_t(const FQName& fqName, const Coordinator* coordinator,
                                   const GetFormatter& getFormatter)>;

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

        return mGenerationFunction(fqName, coordinator, [&] {
            return coordinator->getFormatter(fqName, location, getFileName(fqName));
        });
    }

    // 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->definedName());
        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;
                break;
            }

            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](const FQName& fqName, const Coordinator* coordinator,
                      const FileGenerator::GetFormatter& getFormatter) -> 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

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

        (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(const FQName& fqName, const Coordinator* coordinator,
                                       const FileGenerator::GetFormatter& getFormatter) {
    AST* ast;
    std::string limitToType;
    FQName typeName;

    // See appendPerTypeTargets.
    // 'a.b.c@1.0::types.Foo' is used to compile 'Foo' for Java even though in
    // the rest of the compiler, this type is simply called 'a.b.c@1.0::Foo'.
    // However, here, we need to disambiguate an interface name and a type in
    // types.hal in order to figure out what to parse, so this legacy behavior
    // is kept.
    if (fqName.name().find("types.") == 0) {
        limitToType = fqName.name().substr(strlen("types."));

        ast = coordinator->parse(fqName.getTypesForPackage());

        const auto& names = fqName.names();
        CHECK(names.size() == 2 && names[0] == "types") << fqName.string();
        typeName = FQName(fqName.package(), fqName.version(), names[1]);
    } else {
        ast = coordinator->parse(fqName);
        typeName = fqName;
    }
    if (ast == nullptr) {
        fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());
        return UNKNOWN_ERROR;
    }

    Type* type = ast->lookupType(typeName, &ast->getRootScope());
    CHECK(type != nullptr) << typeName.string();
    if (!type->isJavaCompatible()) {
        return OK;
    }

    Formatter out = getFormatter();
    if (!out.isValid()) {
        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.

    std::vector<NamedType*> subTypes = typesAST->getRootScope().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 libhidlbase.
    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(const FQName& packageFQName,
                                          const Coordinator* coordinator,
                                          const FileGenerator::GetFormatter& getFormatter) {
    std::vector<FQName> packageInterfaces;
    status_t err =
        coordinator->appendPackageInterfacesToVector(packageFQName,
                                                     &packageInterfaces);
    if (err != OK) {
        return err;
    }

    // b/146223994: parse all interfaces
    // - causes files to get read (filling out dep file)
    // - avoid creating successful output for broken files
    for (const FQName& 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;
        }
    }

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

    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(const FQName& packageFQName,
                                            const Coordinator* coordinator,
                                            const FileGenerator::GetFormatter& getFormatter) {
    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 system_ext partition.
    bool isSystemExt = !isCoreAndroid;

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

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

    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 (isSystemExt) {
            out << "system_ext_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";
        }
        // Explicity call this out for developers.
        out << "gen_java: " << (genJavaLibrary ? "true" : "false") << ",\n";
        if (genJavaConstants) {
            out << "gen_java_constants: true,\n";
        }
   }).endl();

    return OK;
}

static status_t generateAndroidBpImplForPackage(const FQName& packageFQName,
                                                const Coordinator* coordinator,
                                                const FileGenerator::GetFormatter& getFormatter) {
    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);
    }

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

    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"
                << "\"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. In addition, vectors of arrays are limited to at most one-dimensional "
                    "arrays and vectors of {vectors,interfaces,memory} are not supported.\n",
                    fqName.string().c_str());
            return false;
        }
    }

    return true;
}

FileGenerator::GenerationFunction generateExportHeaderForPackage(bool forJava) {
    return [forJava](const FQName& packageFQName, const Coordinator* coordinator,
                     const FileGenerator::GetFormatter& getFormatter) -> 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;
        }

        Formatter out = getFormatter();
        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(const FQName& fqName, const Coordinator* coordinator,
                                   const FileGenerator::GetFormatter& getFormatter) {
    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;
    }

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

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

    return OK;
}

static status_t generateFunctionCount(const FQName& fqName, const Coordinator* coordinator,
                                      const FileGenerator::GetFormatter& getFormatter) {
    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;
    }

    Formatter out = getFormatter();
    if (!out.isValid()) {
        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-impl",
        "Generates boilerplate implementation of a hidl interface in Java (for convenience).",
        OutputMode::NEEDS_DIR,
        Coordinator::Location::DIRECT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::generateForInterfaces,
                [](const FQName& fqName) { return fqName.getInterfaceBaseName() + ".java"; },
                astGenerationFunction(&AST::generateJavaImpl),
            },
        }
    },
    {
        "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),
            },
        },
    },
    {
        "inheritance-hierarchy",
        "Prints the hierarchy of inherited types as a JSON object.",
        OutputMode::NOT_NEEDED,
        Coordinator::Location::STANDARD_OUT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                nullptr /* file name for fqName */,
                astGenerationFunction(&AST::generateInheritanceHierarchy),
            },
        },
    },
    {
        "format",
        "Reformats the .hal files",
        OutputMode::NEEDS_SRC,
        Coordinator::Location::PACKAGE_ROOT,
        GenerationGranularity::PER_FILE,
        validateForSource,
        {
            {
                FileGenerator::alwaysGenerate,
                [](const FQName& fqName) { return fqName.name() + ".hal"; },
                astGenerationFunction(&AST::generateFormattedHidl),
            },
        }
    },
};
// clang-format on

static void usage(const char* me) {
    Formatter out(stderr);

    out << "Usage: " << me << " -o <output path> -L <language> [-O <owner>] ";
    Coordinator::emitOptionsUsageString(out);
    out << " FQNAME...\n\n";

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

    out.indent();
    out.indent();

    out << "-h: Prints this menu.\n";
    out << "-L <language>: The following options are available:\n";
    out.indent([&] {
        for (auto& e : kFormats) {
            std::stringstream sstream;
            sstream.fill(' ');
            sstream.width(16);
            sstream << std::left << e.name();

            out << sstream.str() << ": " << e.description() << "\n";
        }
    });
    out << "-O <owner>: The owner of the module for -Landroidbp(-impl)?.\n";
    out << "-o <output path>: Location to output files.\n";
    Coordinator::emitOptionsDetailString(out);

    out.unindent();
    out.unindent();
}

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

    coordinator.parseOptions(argc, argv, "ho:O:L:", [&](int res, char* arg) {
        switch (res) {
            case 'o': {
                if (!outputPath.empty()) {
                    fprintf(stderr, "ERROR: -o <output path> can only be specified once.\n");
                    exit(1);
                }
                outputPath = arg;
                break;
            }

            case 'O': {
                if (!coordinator.getOwner().empty()) {
                    fprintf(stderr, "ERROR: -O <owner> can only be specified once.\n");
                    exit(1);
                }
                coordinator.setOwner(arg);
                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() == arg) {
                        outputFormat = &e;
                        break;
                    }
                }
                if (outputFormat == nullptr) {
                    fprintf(stderr, "ERROR: unrecognized -L option: \"%s\".\n", arg);
                    exit(1);
                }
                break;
            }

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

    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);

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