/*
 * Copyright 2023 WebAssembly Community Group participants
 *
 * 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.
 */

//
// A WebAssembly merger: loads multiple files, mashes them together, and emits
// the result. Unlike wasm-ld, this does not have the full semantics of native
// linkers. Instead, wasm-merge does at compile time what you can do with JS at
// runtime: connect some wasm modules together by hooking up imports to exports.
// The result of wasm-merge is a single module that behaves the same as the
// multiple original modules, but you don't need that JS to set up the
// connections between the modules any more, and DCE and inlining can help
// inside the module, etc. In other words, wasm-merge is sort of like a wasm
// bundler, where "bundler" means something similar to JS bundlers. (While JS is
// mentioned here a lot, wasm-merge could in principle also be helpful with
// optimizing other ways of connecting modules at compile time instead of
// runtime, like perhaps the component model for wasm that is in development.)
//
// The specific merging model here is to take N wasm modules, each with a given
// name:
//
//   wasm_1, wasm_2, ... , wasm_N
//   name_1, name_2, ... , name_N
//
// We resolve imports and exports using those names as we merge all the code
// into the final module. That is, if wasm_i imports "foo.bar", and wasm_j has
// name name_j == "foo" and it exports a function "bar" then wasm_i's import of
// "foo.bar" will turn into a reference to the proper item from wasm_j that
// corresponds to that export:
//
//  (module "first"
//    (import "foo" "bar" (func $foo.bar))
//    (func $other
//      (call $foo.bar)
//    )
//  )
//
//  (module "foo"
//    (func $f (export "bar")
//      ..
//    )
//  )
//
// => wasm-merge =>
//
//  (module
//    ..
//    (func $other
//      (call $f) ;; call $f directly since "foo.bar" resolved as $f
//    )
//    (func $f
//      ..
//    )
//  )
//
// We call that process "fusing" of imports to exports. Note that we don't
// bother to optimize here - we don't remove either the export or the import,
// even if we fuse - as it is simple to leave that for later optimizations
// (removing unwanted exports can be done using wasm-metadce, see
// https://github.com/WebAssembly/binaryen/wiki/Pruning-unneeded-code-in-wasm-files-with-wasm-metadce#example-pruning-exports
// ).
//
// Note that we allow "forward references" - a reference from an earlier module
// to a later one. If one instantiates the wasm modules in sequence then that is
// impossible to do, and to work around it e.g. emscripten dynamic linking
// support will add a thunk. Note that ES6 modules support such circular imports
// for JS, but they are considered annoying even there; one of the solutions to
// such import loops in JS is to merge the modules together, and similarly
// wasm-merge can help wasm build systems avoid such cycles. (Note that ES6
// module support for *wasm* is not intended to support cycles, unlike JS, and
// so avoiding cycles is important.)
//
// Despite resolving imports and exports without regard for the order of
// modules, the order does matter in one way: if the modules have start
// functions then those are called in the given order of the modules.
//
// wasm-merge works in linear time (linear in the total code in all the linked
// modules). Each input module is traversed once to fix up names before being
// merged, and at the end we traverse the entire merged module once to fuse
// imports and exports.
//
// Debugging: Set BINARYEN_PASS_DEBUG=1 in the env to get validation after each
// merging of a module (like pass-debug mode for the pass runner, this does
// expensive work after each incremental operation). This can take quadratic
// time, so we do not do it by default.
//

#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/utils.h"
#include "support/colors.h"
#include "support/file.h"
#include "wasm-builder.h"
#include "wasm-io.h"
#include "wasm-validator.h"
#include "wasm.h"

#include "tool-options.h"

using namespace wasm;

namespace {

// The module we'll merge into. This is a singleton and it is simple to just
// have it as a global rather than pass it around all the time.
Module merged;

// Everything we merge is accumulated into |merged|, aside from the start
// functions. To avoid incrementally adding a call each time, which can end up
// nested, we add them here and generate a series of flat calls at the end.
std::vector<Name> startFunctions;

// Name conflicts on functions etc. are resolved by renaming things in a way
// that only matters internally. Conflicting export names, however, are
// observable, and so the user must decide how they want wasm-merge to handle
// that.
enum ExportMergeMode {
  // Error on name conflicts. This is the least surprising mode, and the one
  // used by default.
  ErrorOnExportConflicts,
  // Rename conflicting exports. Later exports will get a suffix added to them
  // to make them unique. For example, this is useful if you merge several
  // modules that each have a "main" export, and it's fine if those are renamed
  // to "main", "main_1", "main_2" etc. - you'll decide when to call each of
  // those and do so at the right time.
  RenameExportConflicts,
  // Silently ignore export conflicts, that is, later exports that overlap with
  // previous ones are simply skipped. This can be useful when the first module
  // is the main program, which exports things to the outside, while other
  // modules are libraries of code that only provide things to the main module
  // but not to the outside.
  SkipExportConflicts,
} exportMergeMode = ErrorOnExportConflicts;

// Merging two modules is mostly straightforward: copy the functions etc. of the
// first module into the second, with some renaming to avoid name collisions.
// The only other thing we need to handle is the mapping of imports to exports,
// as explained earlier. The way we handle this is to first combine the modules
// into a single module, then connect imports and imports. To do that we track
// the origin of each export.
//
// For example, in the example from earlier we have this as the second module:
//
//  (module "foo"
//    (func $f (export "bar")
//      ..
//    )
//  )
//
// We will annotate that exported function as being from module "foo", so that
// we can resolve imports to "foo.bar" to it. The ExportInfo data structure
// tracks the extra info we need for exports as we go.
struct ExportInfo {
  // The name of the module this export originally appeared in, as just
  // explained.
  Name moduleName;
  // The name of the export itself, which is the basename (the export will be
  // used as module.base). This is normally just the same as export->name, but
  // we need to stash it here because exports may be renamed when merged in, if
  // there is overlap with the name of another export, and imports refer to the
  // original name.
  Name baseName;
};
std::unordered_map<Export*, ExportInfo> exportModuleMap;

// A map of [kind of thing in the module] to [old name => new name] for things
// of that kind. For example, the NameUpdates for functions is a map of old
// function names to new function names.
using NameUpdates = std::unordered_map<Name, Name>;
using KindNameUpdates = std::unordered_map<ModuleItemKind, NameUpdates>;

// Apply a set of name changes to a module.
void updateNames(Module& wasm, KindNameUpdates& kindNameUpdates) {
  if (kindNameUpdates.empty()) {
    return;
  }

  struct NameMapper
    : public WalkerPass<
        PostWalker<NameMapper, UnifiedExpressionVisitor<NameMapper>>> {
    bool isFunctionParallel() override { return true; }

    std::unique_ptr<Pass> create() override {
      return std::make_unique<NameMapper>(kindNameUpdates);
    }

    KindNameUpdates& kindNameUpdates;

    NameMapper(KindNameUpdates& kindNameUpdates)
      : kindNameUpdates(kindNameUpdates) {}

    void visitExpression(Expression* curr) {
#define DELEGATE_ID curr->_id

#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>();

#define DELEGATE_GET_FIELD(id, field) cast->field

#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_CHILD(id, field)
#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)
#define DELEGATE_FIELD_INT(id, field)
#define DELEGATE_FIELD_LITERAL(id, field)
#define DELEGATE_FIELD_NAME(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)

#define DELEGATE_FIELD_NAME_KIND(id, field, kind)                              \
  if (cast->field.is()) {                                                      \
    mapName(kind, cast->field);                                                \
  }

#include "wasm-delegations-fields.def"
    }

    // Aside from expressions, we have a few other things we need to update at
    // the module scope.
    void mapModuleFields(Module& wasm) {
      for (auto& curr : wasm.exports) {
        // skip type exports
        if (auto* name = curr->getInternalName()) {
          mapName(ModuleItemKind(curr->kind), *name);
        }
      }
      for (auto& curr : wasm.elementSegments) {
        mapName(ModuleItemKind::Table, curr->table);
      }
      for (auto& curr : wasm.dataSegments) {
        mapName(ModuleItemKind::Memory, curr->memory);
      }

      mapName(ModuleItemKind::Function, wasm.start);
    }

  private:
    Name resolveName(NameUpdates& updates, Name newName, Name oldName) {
      // Iteratively lookup the updated name.
      std::set<Name> visited;
      auto name = newName;
      while (1) {
        auto iter = updates.find(name);
        if (iter == updates.end()) {
          return name;
        }
        if (visited.contains(name)) {
          // This is a loop of imports, which means we cannot resolve a useful
          // name. Report an error.
          Fatal() << "wasm-merge: infinite loop of imports on " << oldName;
        }
        visited.insert(name);
        name = iter->second;
      }
    }

    void mapName(ModuleItemKind kind, Name& name) {
      auto iter = kindNameUpdates.find(kind);
      if (iter == kindNameUpdates.end()) {
        return;
      }
      auto& nameUpdates = iter->second;
      auto iter2 = nameUpdates.find(name);
      if (iter2 != nameUpdates.end()) {
        name = resolveName(nameUpdates, iter2->second, name);
      }
    }
  } nameMapper(kindNameUpdates);

  PassRunner runner(&wasm);
  nameMapper.run(&runner, &wasm);
  nameMapper.runOnModuleCode(&runner, &wasm);
  nameMapper.mapModuleFields(wasm);
}

// Scan an input module to find the names of the items it contains, and pick new
// names for them that do not cause conflicts with things already in the merged
// module.
void renameInputItems(Module& input) {
  // Pick the names, and apply them to the items themselves.
  // TODO Add ModuleUtils::iterAll + getValidName(kind, ..)? Then we could
  //      avoid hardcoded loops here, but it's unclear those would help
  //      anywhere else.
  KindNameUpdates kindNameUpdates;

  // Add a mapping of a name to a new name, in a particular kind. If the new
  // name is the same as the old, do nothing.
  auto maybeAdd = [&](ModuleItemKind kind, Name& name, const Name newName) {
    if (newName != name) {
      kindNameUpdates[kind][name] = newName;
      name = newName;
    }
  };

  for (auto& curr : input.functions) {
    auto name = Names::getValidFunctionName(merged, curr->name);
    maybeAdd(ModuleItemKind::Function, curr->name, name);
  }
  for (auto& curr : input.globals) {
    auto name = Names::getValidGlobalName(merged, curr->name);
    maybeAdd(ModuleItemKind::Global, curr->name, name);
  }
  for (auto& curr : input.tags) {
    auto name = Names::getValidTagName(merged, curr->name);
    maybeAdd(ModuleItemKind::Tag, curr->name, name);
  }
  for (auto& curr : input.elementSegments) {
    auto name = Names::getValidElementSegmentName(merged, curr->name);
    maybeAdd(ModuleItemKind::ElementSegment, curr->name, name);
  }
  for (auto& curr : input.memories) {
    auto name = Names::getValidMemoryName(merged, curr->name);
    maybeAdd(ModuleItemKind::Memory, curr->name, name);
  }
  for (auto& curr : input.dataSegments) {
    auto name = Names::getValidDataSegmentName(merged, curr->name);
    maybeAdd(ModuleItemKind::DataSegment, curr->name, name);
  }
  for (auto& curr : input.tables) {
    auto name = Names::getValidTableName(merged, curr->name);
    maybeAdd(ModuleItemKind::Table, curr->name, name);
  }

  // Apply the names to their uses.
  updateNames(input, kindNameUpdates);
}

void copyModuleContents(Module& input, Name inputName) {
  // First, copy the regular module items (functions, globals) etc. which we
  // have proper names for, and can just copy.
  ModuleUtils::copyModuleItems(input, merged);

  // We must handle exports in a special way, as we need to note their origin
  // module as we copy them in (also, they are not importable or exportable, so
  // the ModuleUtils function above does not handle them).
  for (auto& curr : input.exports) {
    auto copy = std::make_unique<Export>(*curr);

    // Note the module origin and original name of this export, for later fusing
    // of imports to exports.
    exportModuleMap[copy.get()] = ExportInfo{inputName, curr->name};

    // An export may already exist with that name, so fix it up.
    copy->name = Names::getValidExportName(merged, copy->name);
    if (copy->name != curr->name) {
      if (exportMergeMode == ErrorOnExportConflicts) {
        Fatal() << "Export name conflict: " << curr->name << " (consider"
                << " --rename-export-conflicts or"
                << " --skip-export-conflicts)\n";
      } else if (exportMergeMode == SkipExportConflicts) {
        // Skip the addExport below us.
        continue;
      }
    }
    // Add the export.
    merged.addExport(std::move(copy));
  }

  // Start functions are accumulated till the end.
  if (input.start) {
    startFunctions.push_back(input.start);
  }

  // TODO: type names, features, debug info, custom sections, dylink info, etc.
}

void reportTypeMismatch(bool& valid, const char* kind, Importable* import) {
  valid = false;
  std::cerr << "Type mismatch when importing " << kind << " " << import->base
            << " from module " << import->module << " ($" << import->name
            << "): ";
}

// Check that the export and import limits match.
template<typename T>
void checkLimit(bool& valid, const char* kind, T* export_, T* import) {
  if (export_->initial < import->initial) {
    reportTypeMismatch(valid, kind, import);
    std::cerr << "minimal size " << export_->initial
              << " is smaller than expected minimal size " << import->initial
              << ".\n";
  }
  if (import->hasMax()) {
    if (!export_->hasMax()) {
      reportTypeMismatch(valid, kind, import);
      std::cerr << "expecting a bounded " << kind
                << " but the "
                   "imported "
                << kind << " is unbounded.\n";
    } else if (export_->max > import->max) {
      reportTypeMismatch(valid, kind, import);
      std::cerr << "maximal size " << export_->max
                << " is larger than expected maximal size " << import->max
                << ".\n";
    }
  }
}

// Find pairs of matching imports and exports, and make uses of the import refer
// to the exported item (which has been merged into the module).
void fuseImportsAndExports(const PassOptions& options) {
  // First, scan the exports and build a map. We build a map of [module name] to
  // [export name => internal name]. For example, consider this module:
  //
  //  (module "module_A"
  //    (func $foo (export "bar"))
  //  )
  //
  // Then the ModuleExportMap will be:
  //
  //  {
  //    "module_A": {
  //      "bar": "foo";
  //    }
  //  }
  //
  using ModuleExportMap = std::unordered_map<Name, NameUpdates>;

  // A map of ModuleExportMaps, one per item kind (one for functions, one for
  // globals, etc.).
  using KindModuleExportMaps =
    std::unordered_map<ExternalKind, ModuleExportMap>;
  KindModuleExportMaps kindModuleExportMaps;

  for (auto& ex : merged.exports) {
    // skip type exports
    if (auto* name = ex->getInternalName()) {
      assert(exportModuleMap.contains(ex.get()));
      ExportInfo& exportInfo = exportModuleMap[ex.get()];
      kindModuleExportMaps[ex->kind][exportInfo.moduleName]
                          [exportInfo.baseName] = *name;
    }
  }

  // Find all the imports and see which have corresponding exports, which means
  // there is an internal item we can refer to. We build up a map of the names
  // that we should update.
  KindNameUpdates kindNameUpdates;
  ModuleUtils::iterImportable(merged, [&](ExternalKind kind, Importable* curr) {
    if (curr->imported()) {
      auto internalName = kindModuleExportMaps[kind][curr->module][curr->base];
      if (internalName.is()) {
        // We found something to fuse! Add it to the maps for renaming.
        kindNameUpdates[ModuleItemKind(kind)][curr->name] = internalName;
      }
    }
  });

  if (options.validate) {
    // Make sure that the export types match the import types.
    bool valid = true;
    ModuleUtils::iterImportedFunctions(merged, [&](Function* import) {
      auto internalName = kindModuleExportMaps[ExternalKind::Function]
                                              [import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getFunction(internalName);
        // TODO: use Type subtyping when exactness handling is complete.
        if (!HeapType::isSubType(export_->type.getHeapType(),
                                 import->type.getHeapType())) {
          reportTypeMismatch(valid, "function", import);
          std::cerr << "type " << export_->type << " is not a subtype of "
                    << import->type << ".\n";
        }
      }
    });
    ModuleUtils::iterImportedTables(merged, [&](Table* import) {
      auto internalName =
        kindModuleExportMaps[ExternalKind::Table][import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getTable(internalName);
        checkLimit(valid, "table", export_, import);
        if (export_->type != import->type) {
          reportTypeMismatch(valid, "table", import);
          std::cerr << "export type " << export_->type
                    << " is different from import type " << import->type
                    << ".\n";
        }
      }
    });
    ModuleUtils::iterImportedMemories(merged, [&](Memory* import) {
      auto internalName = kindModuleExportMaps[ExternalKind::Memory]
                                              [import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getMemory(internalName);
        if (export_->is64() != import->is64()) {
          reportTypeMismatch(valid, "memory", import);
          std::cerr << "index type should match.\n";
        }
        checkLimit(valid, "memory", export_, import);
      }
    });
    ModuleUtils::iterImportedGlobals(merged, [&](Global* import) {
      auto internalName = kindModuleExportMaps[ExternalKind::Global]
                                              [import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getGlobal(internalName);
        if (export_->mutable_ != import->mutable_) {
          reportTypeMismatch(valid, "global", import);
          std::cerr << "mutability should match.\n";
        }
        if (export_->mutable_ && export_->type != import->type) {
          reportTypeMismatch(valid, "global", import);
          std::cerr << "export type " << export_->type
                    << " is different from import type " << import->type
                    << ".\n";
        }
        if (!export_->mutable_ &&
            !Type::isSubType(export_->type, import->type)) {
          reportTypeMismatch(valid, "global", import);
          std::cerr << "type " << export_->type << " is not a subtype of "
                    << import->type << ".\n";
        }
      }
    });
    ModuleUtils::iterImportedTags(merged, [&](Tag* import) {
      auto internalName =
        kindModuleExportMaps[ExternalKind::Tag][import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getTag(internalName);
        if (export_->type != import->type) {
          reportTypeMismatch(valid, "tag", import);
          std::cerr << "export type " << export_->type
                    << " is different from import type " << import->type
                    << ".\n";
        }
      }
    });
    if (!valid) {
      Fatal() << "import/export mismatches";
    }
  }

  // Update the things we found.
  updateNames(merged, kindNameUpdates);
}

// Things may have been imported using supertypes, which means they can get
// refined after merging.
void updateTypes(Module& wasm) {
  struct Updater : public WalkerPass<PostWalker<Updater>> {
    bool isFunctionParallel() override { return true; }

    std::unique_ptr<Pass> create() override {
      return std::make_unique<Updater>();
    }

    void visitGlobalGet(GlobalGet* curr) {
      curr->type = getModule()->getGlobal(curr->name)->type;
    }

    void visitCall(Call* curr) {
      if (curr->type != Type::unreachable) {
        curr->type = getModule()
                       ->getFunction(curr->target)
                       ->type.getHeapType()
                       .getSignature()
                       .results;
      }
    }

    void visitRefFunc(RefFunc* curr) { curr->finalize(*getModule()); }

    void visitFunction(Function* curr) {
      ReFinalize().walkFunctionInModule(curr, getModule());
    }
  } updater;

  PassRunner runner(&wasm);
  updater.run(&runner, &wasm);
  updater.runOnModuleCode(&runner, &wasm);
}

// Merge the start functions, keeping the order. We add a new function that
// calls them in sequence (leaving proper inlining, including handling of
// control flow etc., to the optimizer).
void mergeStartFunctions() {
  if (startFunctions.empty()) {
    return;
  }

  if (startFunctions.size() == 1) {
    // Avoid adding a call here.
    merged.start = startFunctions[0];
    return;
  }

  auto combinedName =
    Names::getValidFunctionName(merged, "merged.start.combined");
  Builder builder(merged);
  std::vector<Expression*> calls;
  for (auto start : startFunctions) {
    calls.push_back(builder.makeCall(start, {}, Type::none));
  }
  auto* body = builder.makeBlock(calls);
  auto combined = builder.makeFunction(
    combinedName, Signature(Type::none, Type::none), {}, body);
  merged.addFunction(std::move(combined));
  merged.start = combinedName;
}

// Merges an input module into an existing target module. The input module can
// be modified, as it will no longer be needed (so it is intentionally not
// marked as const here).
void mergeInto(Module& input, Name inputName) {
  // Rename things in the input module so that there are no conflicts with names
  // in the merged module. We do so in place for efficiency.
  renameInputItems(input);

  // The input module's items can now be copied into the target module safely,
  // as names will not conflict.
  copyModuleContents(input, inputName);
}

} // anonymous namespace

int main(int argc, const char* argv[]) {
  std::vector<std::string> inputFiles;
  std::vector<std::string> inputFileNames;
  bool emitBinary = true;
  bool debugInfo = false;
  std::map<size_t, std::string> inputSourceMapFilenames;
  std::string outputSourceMapFilename;
  std::string outputSourceMapUrl;

  // We can write wasm-split manifests that can later be fed to wasm-split to
  // split the merged module back up along the lines of the original modules.
  // Map modules to their functions so we can write the manifest.
  std::string manifestFile;
  std::unordered_map<Name, std::vector<Name>> moduleFuncs;

  const std::string WasmMergeOption = "wasm-merge options";

  ToolOptions options("wasm-merge",
                      R"(Merge wasm files into one.

For example,

  wasm-merge foo.wasm foo bar.wasm bar -o merged.wasm

will read foo.wasm and bar.wasm, with names 'foo' and 'bar' respectively, so if the second imports from 'foo', we will see that as an import from the first module after the merge. The merged output will be written to merged.wasm.

Note that filenames and modules names are interleaved (which is hopefully less confusing).

Input source maps can be specified by adding an -ism option right after the module name:

  wasm-merge foo.wasm foo -ism foo.wasm.map ...)");

  options
    .add("--output",
         "-o",
         "Output file",
         WasmMergeOption,
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["output"] = argument;
           Colors::setEnabled(false);
         })
    .add_positional("INFILE1 NAME1 INFILE2 NAME2 [..]",
                    Options::Arguments::N,
                    [&](Options* o, const std::string& argument) {
                      if (inputFiles.size() == inputFileNames.size()) {
                        inputFiles.push_back(argument);
                      } else {
                        inputFileNames.push_back(argument);
                      }
                    })
    .add("--input-source-map",
         "-ism",
         "Consume source maps from the specified files",
         WasmMergeOption,
         Options::Arguments::N,
         [&](Options* o, const std::string& argument) {
           size_t pos = inputFiles.size();
           if (pos == 0 || pos != inputFileNames.size() ||
               inputSourceMapFilenames.contains(pos - 1)) {
             std::cerr << "Option '-ism " << argument
                       << "' should be right after the module name\n";
             exit(EXIT_FAILURE);
           }
           inputSourceMapFilenames.insert({pos - 1, argument});
         })
    .add("--output-source-map",
         "-osm",
         "Emit source map to the specified file",
         WasmMergeOption,
         Options::Arguments::One,
         [&outputSourceMapFilename](Options* o, const std::string& argument) {
           outputSourceMapFilename = argument;
         })
    .add("--output-source-map-url",
         "-osu",
         "Emit specified string as source map URL",
         WasmMergeOption,
         Options::Arguments::One,
         [&outputSourceMapUrl](Options* o, const std::string& argument) {
           outputSourceMapUrl = argument;
         })
    .add("--output-manifest",
         "",
         "Write a wasm-split manifest to the specified file. This manifest can "
         "be given to wasm-split to split the merged module along the lines of "
         "the original modules. Implies --debuginfo to preserve function names "
         "in the output module.",
         WasmMergeOption,
         Options::Arguments::One,
         [&](Options* o, const std::string& argument) {
           manifestFile = argument;
           debugInfo = true;
         })
    .add("--rename-export-conflicts",
         "-rec",
         "Rename exports to avoid conflicts (rather than error)",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) {
           exportMergeMode = RenameExportConflicts;
         })
    .add("--skip-export-conflicts",
         "-sec",
         "Skip exports that conflict with previous ones",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) {
           exportMergeMode = SkipExportConflicts;
         })
    .add("--emit-text",
         "-S",
         "Emit text instead of binary for the output file",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) { emitBinary = false; })
    .add("--debuginfo",
         "-g",
         "Emit names section and debug info",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& arguments) { debugInfo = true; });
  options.parse(argc, argv);

  if (inputFiles.size() != inputFileNames.size()) {
    Fatal() << "Please provide an import name for each input file. "
               "In particular, the number of positional inputs must be even as "
               "each wasm binary must be followed by its name.";
  }

  // Process the inputs.
  // TODO: If the inputs are a very large number of small modules then it might
  //       make sense to parallelize this. (If so, then changing the existing
  //       parallelism above in NameMapper might make sense.)

  for (Index i = 0; i < inputFiles.size(); i++) {
    auto inputFile = inputFiles[i];
    auto inputFileName = inputFileNames[i];
    auto iter = inputSourceMapFilenames.find(i);
    auto inputSourceMapFilename =
      (iter == inputSourceMapFilenames.end()) ? "" : iter->second;

    if (options.debug) {
      std::cerr << "reading input '" << inputFile << "' as '" << inputFileName
                << "'...\n";
    }

    // For the first input, we'll just read it in directly. For later inputs,
    // we read them and then merge.
    std::unique_ptr<Module> laterInput;
    Module* currModule;
    if (i == 0) {
      currModule = &merged;
    } else {
      laterInput = std::make_unique<Module>();
      currModule = laterInput.get();
    }

    options.applyOptionsBeforeParse(*currModule);

    ModuleReader reader;
    try {
      reader.read(inputFile, *currModule, inputSourceMapFilename);
    } catch (ParseException& p) {
      p.dump(std::cerr);
      Fatal() << "error in parsing wasm input: " << inputFile;
    }

    options.applyOptionsAfterParse(*currModule);

    if (options.passOptions.validate) {
      if (!WasmValidator().validate(*currModule)) {
        std::cout << *currModule << '\n';
        Fatal() << "error in validating input: " << inputFile;
      }
    }

    if (!laterInput) {
      // This is the very first module, which we read directly into |merged|.
      // The only other operation we need to do is note the exports for later.
      for (auto& curr : merged.exports) {
        exportModuleMap[curr.get()] = ExportInfo{inputFileName, curr->name};
      }

      // Start functions are accumulated till the end.
      if (merged.start) {
        startFunctions.push_back(merged.start);
        merged.start = Name();
      }

    } else {
      // This is a later module: do a full merge.
      mergeInto(*currModule, inputFileName);

      // The functions in the module have been renamed and copied rather than
      // moved, so we can get their final names directly. (We don't need this
      // for the first module because it does not appear in the manifest.)
      auto& funcs = moduleFuncs[inputFileName];
      for (auto& func : currModule->functions) {
        if (!func->imported()) {
          funcs.push_back(func->name);
        }
      }

      // Validate after each merged module, when we are in pass-debug mode
      // (this can be quadratic time).
      if (PassRunner::getPassDebug()) {
        std::cerr << "[WasmMerge]   merged : " << inputFile << '\n';
        if (options.passOptions.validate && !WasmValidator().validate(merged)) {
          std::cout << merged << '\n';
          Fatal() << "error in validating after: " << inputFile;
        }
      }
    }
  }

  // Fuse imports and exports now that everything is all together in the merged
  // module.
  fuseImportsAndExports(options.passOptions);

  // Update types after combing and linking everything.
  updateTypes(merged);

  // Merge the start functions, after everything else is set up.
  mergeStartFunctions();

  {
    PassRunner passRunner(&merged);
    // We might have made some globals read from others that now appear after
    // them (if the one they read was appended from a later module). Sort them
    // to fix that. TODO: we could do this only if we actually append globals
    passRunner.add("reorder-globals-always");
    // Remove unused things. This is obviously a useful optimization but it also
    // makes using the output easier: if an import was resolved by an export
    // during the merge, then that import will have no more uses and it will be
    // optimized out (while if we didn't optimize it out then instantiating the
    // module would still be forced to provide something for that import).
    passRunner.add("remove-unused-module-elements");
    passRunner.run();
  }

  // Without pass-debug mode, validate once at the very end.
  if (!PassRunner::getPassDebug() && options.passOptions.validate &&
      !WasmValidator().validate(merged)) {
    std::cout << merged << '\n';
    Fatal() << "error in validating final merged";
  }

  // Output.
  if (!manifestFile.empty()) {
    std::ofstream manifest(manifestFile);
    // Skip module 0 because it will be the primary module for the split and
    // does not need to appear in the manifest.
    for (size_t i = 1; i < inputFileNames.size(); i++) {
      auto moduleName = inputFileNames[i];
      const auto& funcs = moduleFuncs[moduleName];
      if (funcs.empty()) {
        continue;
      }

      manifest << moduleName << "\n";
      for (auto func : funcs) {
        manifest << func << "\n";
      }
      manifest << "\n";
    }
  }

  if (options.extra.contains("output")) {
    ModuleWriter writer(options.passOptions);
    writer.setBinary(emitBinary);
    writer.setDebugInfo(debugInfo);
    if (outputSourceMapFilename.size()) {
      writer.setSourceMapFilename(outputSourceMapFilename);
      writer.setSourceMapUrl(outputSourceMapUrl);
    }
    writer.write(merged, options.extra["output"]);
  }

  flush_and_quick_exit(0);
}
