/*
 * Copyright 2018 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.
 */

#ifndef wasm_tools_tool_options_h
#define wasm_tools_tool_options_h

#include "ir/module-utils.h"
#include "pass.h"
#include "support/command-line.h"
#include "wasm-io.h"

//
// Shared options for commandline tools
//

namespace wasm {

struct ToolOptions : public Options {
  PassOptions passOptions;

  bool quiet = false;
  bool preserveTypeOrder = false;
  bool emitModuleNames = false;
  IRProfile profile = IRProfile::Normal;

  constexpr static const char* ToolOptionsCategory = "Tool options";

  ToolOptions(const std::string& command, const std::string& description)
    : Options(command, description) {
    (*this)
      .add("--mvp-features",
           "-mvp",
           "Disable all non-MVP features",
           ToolOptionsCategory,
           Arguments::Zero,
           [this](Options*, const std::string&) {
             enabledFeatures.setMVP();
             disabledFeatures.setAll();
           })
      .add("--all-features",
           "-all",
           "Enable all features",
           ToolOptionsCategory,
           Arguments::Zero,
           [this](Options*, const std::string&) {
             enabledFeatures.setAll();
             disabledFeatures.setMVP();
           })
      .add("--detect-features",
           "",
           "(deprecated - this flag does nothing)",
           ToolOptionsCategory,
           Arguments::Zero,
           [](Options*, const std::string&) {})
      .add("--quiet",
           "-q",
           "Emit less verbose output and hide trivial warnings.",
           ToolOptionsCategory,
           Arguments::Zero,
           [this](Options*, const std::string&) { quiet = true; })
      .add("--experimental-poppy",
           "",
           "Parse wast files as Poppy IR for testing purposes.",
           ToolOptionsCategory,
           Arguments::Zero,
           [this](Options*, const std::string&) { profile = IRProfile::Poppy; })
      .add("--emit-module-names",
           "",
           "Emit module names, even if not emitting the rest of the names "
           "section.",
           ToolOptionsCategory,
           Arguments::Zero,
           [this](Options*, const std::string&) { emitModuleNames = true; });
    (*this)
      .addFeature(FeatureSet::SignExt, "sign extension operations")
      .addFeature(FeatureSet::Atomics, "atomic operations")
      .addFeature(FeatureSet::MutableGlobals, "mutable globals")
      .addFeature(FeatureSet::TruncSat, "nontrapping float-to-int operations")
      .addFeature(FeatureSet::SIMD, "SIMD operations and types")
      .addFeature(FeatureSet::BulkMemory,
                  "bulk memory operations",
                  FeatureSet(FeatureSet::BulkMemoryOpt))
      .addFeature(FeatureSet::BulkMemoryOpt,
                  "memory.copy and memory.fill",
                  FeatureSet::None,
                  FeatureSet(FeatureSet::BulkMemory))
      .addFeature(FeatureSet::CallIndirectOverlong,
                  "LEB encoding of call-indirect (Ignored for compatibility as "
                  "it has no effect on Binaryen)")
      .addFeature(FeatureSet::ExceptionHandling,
                  "exception handling operations")
      .addFeature(FeatureSet::TailCall, "tail call operations")
      .addFeature(FeatureSet::ReferenceTypes, "reference types")
      .addFeature(FeatureSet::Multivalue, "multivalue functions")
      .addFeature(FeatureSet::GC, "garbage collection")
      .addFeature(FeatureSet::Memory64, "memory64")
      .addFeature(FeatureSet::RelaxedSIMD, "relaxed SIMD")
      .addFeature(FeatureSet::ExtendedConst, "extended const expressions")
      .addFeature(FeatureSet::Strings, "strings")
      .addFeature(FeatureSet::MultiMemory, "multimemory")
      .addFeature(FeatureSet::StackSwitching, "stack switching")
      .addFeature(FeatureSet::SharedEverything, "shared-everything threads")
      .addFeature(FeatureSet::FP16, "float 16 operations")
      .addFeature(FeatureSet::CustomDescriptors,
                  "custom descriptors (RTTs) and exact references")
      .addFeature(FeatureSet::Multibyte, "multibyte array loads and stores")
      .addFeature(FeatureSet::RelaxedAtomics,
                  "acquire/release atomic memory operations")
      .addFeature(FeatureSet::CustomPageSizes, "custom page sizes")
      .addFeature(FeatureSet::WideArithmetic, "wide arithmetic")
      .addFeature(FeatureSet::CompactImports, "compact import section")
      .add("--enable-typed-function-references",
           "",
           "Deprecated compatibility flag",
           ToolOptionsCategory,
           Options::Arguments::Zero,
           [](Options* o, const std::string& argument) {
             std::cerr
               << "Warning: Typed function references have been made part of "
                  "GC and --enable-typed-function-references is deprecated\n";
           })
      .add("--disable-typed-function-references",
           "",
           "Deprecated compatibility flag",
           ToolOptionsCategory,
           Options::Arguments::Zero,
           [](Options* o, const std::string& argument) {
             std::cerr
               << "Warning: Typed function references have been made part of "
                  "GC and --disable-typed-function-references is deprecated\n";
           })
      .add("--no-validation",
           "-n",
           "Disables validation, assumes inputs are correct",
           ToolOptionsCategory,
           Options::Arguments::Zero,
           [this](Options* o, const std::string& argument) {
             passOptions.validate = false;
           })
      .add("--pass-arg",
           "-pa",
           "An argument passed along to optimization passes being run. Must be "
           "in the form KEY@VALUE.  If KEY is the name of a pass then it "
           "applies to the closest instance of that pass before us. If KEY is "
           "not the name of a pass then it is a global option that applies to "
           "all pass instances that read it.",
           ToolOptionsCategory,
           Options::Arguments::N,
           [this](Options*, const std::string& argument) {
             std::string key, value;
             auto colon = argument.find('@');
             if (colon == std::string::npos) {
               key = argument;
               value = "1";
             } else {
               key = argument.substr(0, colon);
               value = argument.substr(colon + 1);
             }

             addPassArg(key, value);
           })
      .add(
        "--closed-world",
        "-cw",
        "Assume code outside of the module does not inspect or interact with "
        "GC and function references, even if they are passed out. The outside "
        "may hold on to them and pass them back in, but not inspect their "
        "contents or call them.",
        ToolOptionsCategory,
        Options::Arguments::Zero,
        [this](Options*, const std::string&) {
          passOptions.worldMode = WorldMode::Closed;
        })
      .add(
        "--preserve-type-order",
        "",
        "Preserve the order of types from the input (useful for debugging and "
        "testing)",
        ToolOptionsCategory,
        Options::Arguments::Zero,
        [&](Options* o, const std::string& arguments) {
          preserveTypeOrder = true;
        })
      .add("--generate-stack-ir",
           "",
           "generate StackIR during writing",
           ToolOptionsCategory,
           Options::Arguments::Zero,
           [&](Options* o, const std::string& arguments) {
             passOptions.generateStackIR = true;
           })
      .add("--optimize-stack-ir",
           "",
           "optimize StackIR during writing",
           ToolOptionsCategory,
           Options::Arguments::Zero,
           [&](Options* o, const std::string& arguments) {
             // Also generate StackIR, to have something to optimize.
             passOptions.generateStackIR = true;
             passOptions.optimizeStackIR = true;
           })
      .add("--print-stack-ir",
           "",
           "print StackIR during writing",
           ToolOptionsCategory,
           Options::Arguments::Zero,
           [&](Options* o, const std::string& arguments) {
             // Also generate StackIR, to have something to print.
             passOptions.generateStackIR = true;
             passOptions.printStackIR = &std::cout;
           });
  }

  ToolOptions& addFeature(FeatureSet::Feature feature,
                          const std::string& description,
                          FeatureSet impliedEnable = FeatureSet::None,
                          FeatureSet impliedDisable = FeatureSet::None) {
    (*this)
      .add(std::string("--enable-") + FeatureSet::toString(feature),
           "",
           std::string("Enable ") + description,
           ToolOptionsCategory,
           Arguments::Zero,
           [this, feature, impliedEnable](Options*, const std::string&) {
             enabledFeatures.set(feature | impliedEnable, true);
             disabledFeatures.set(feature | impliedEnable, false);
           })

      .add(std::string("--disable-") + FeatureSet::toString(feature),
           "",
           std::string("Disable ") + description,
           ToolOptionsCategory,
           Arguments::Zero,
           [this, feature, impliedDisable](Options*, const std::string&) {
             enabledFeatures.set(feature | impliedDisable, false);
             disabledFeatures.set(feature | impliedDisable, true);
           });
    return *this;
  }

  void applyOptionsBeforeParse(Module& module) const {
    module.features.enable(enabledFeatures);
    module.features.disable(disabledFeatures);
  }

  void applyOptionsAfterParse(Module& module) const {
    if (!preserveTypeOrder) {
      module.typeIndices.clear();
    }
  }

  void write(ModuleWriter& writer, Module& wasm, Output& output) const {
    writer.setEmitModuleName(emitModuleNames);
    writer.write(wasm, output);
  }

  void
  write(ModuleWriter& writer, Module& wasm, const std::string& filename) const {
    writer.setEmitModuleName(emitModuleNames);
    writer.write(wasm, filename);
  }

  virtual void addPassArg(const std::string& key, const std::string& value) {
    passOptions.arguments[key] = value;
  }

  virtual ~ToolOptions() = default;

private:
  FeatureSet enabledFeatures = FeatureSet::Default;
  FeatureSet disabledFeatures = FeatureSet::None;
};

} // namespace wasm

#endif
