/*
 * 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");
}

// Keep the list of libs which are used by VNDK core libs and should be part of
// VNDK libs
static const std::vector<std::string> vndkLibs = {
        "android.hardware.audio.common@2.0",
        "android.hardware.configstore@1.0",
        "android.hardware.configstore@1.1",
        "android.hardware.graphics.allocator@2.0",
        "android.hardware.graphics.allocator@3.0",
        "android.hardware.graphics.allocator@4.0",
        "android.hardware.graphics.bufferqueue@1.0",
        "android.hardware.graphics.bufferqueue@2.0",
        "android.hardware.media.bufferpool@2.0",
        "android.hardware.media.omx@1.0",
        "android.hardware.media@1.0",
        "android.hardware.memtrack@1.0",
        "android.hardware.soundtrigger@2.0",
        "android.hidl.token@1.0",
        "android.system.suspend@1.0",
};

bool isVndkCoreLib(const FQName& fqName) {
    return std::find(vndkLibs.begin(), vndkLibs.end(), fqName.string()) != vndkLibs.end();
}

status_t isSystemExtPackage(const FQName& fqName, const Coordinator* coordinator,
                            bool* isSystemExt) {
    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_system_ext", &path);
    if (err != OK) return err;

    const bool exists = fileExists(path);

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

    *isSystemExt = 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 isCoreAndroid = isCoreAndroidPackage(packageFQName);

    bool isVndkCore = isVndkCoreLib(packageFQName);
    bool isVndkSp = isSystemProcessSupportedPackage(packageFQName);

    bool isSystemExtHidl;
    err = isSystemExtPackage(packageFQName, coordinator, &isSystemExtHidl);
    if (err != OK) return err;
    bool isSystemExt = isSystemExtHidl || !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 (isVndkCore || isVndkSp) {
            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;
}
