/*
 * 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"

//
// Shared options for commandline tools
//

namespace wasm {

struct ToolOptions : public Options {
  PassOptions passOptions;

  bool quiet = false;
  bool preserveTypeOrder = 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; });
    (*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::RelaxedAtomics,
                  "acquire/release atomic memory operations")
      .addFeature(FeatureSet::CustomPageSizes, "custom page sizes")
      .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.closedWorld = true;
        })
      .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();
    }
  }

  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
