/*
 * Copyright 2015 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 shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//
#include <memory>

#include "execution-results.h"
#include "ir/element-utils.h"
#include "parser/lexer.h"
#include "parser/wat-parser.h"
#include "pass.h"
#include "shell-interface.h"
#include "support/command-line.h"
#include "support/file.h"
#include "support/result.h"
#include "wasm-binary.h"
#include "wasm-interpreter.h"
#include "wasm-validator.h"

using namespace wasm;

using namespace wasm::WATParser;

struct Shell {
  // Keyed by module name.
  std::map<Name, std::shared_ptr<Module>> modules;

  // Keyed by instance name.
  std::map<Name, std::shared_ptr<ShellExternalInterface>> interfaces;
  std::map<Name, std::shared_ptr<ModuleRunner>> instances;
  // Used for imports, keyed by instance name.
  std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances;

  Name lastInstance;
  std::optional<Name> lastModuleDefinition;

  Options& options;

  Shell(Options& options) : options(options) { buildSpectestModule(); }

  Result<> run(WASTScript& script) {
    size_t i = 0;
    for (auto& entry : script) {
      Colors::red(std::cerr);
      std::cerr << i++ << ' ';
      Colors::normal(std::cerr);
      if (std::get_if<WASTModule>(&entry.cmd)) {
        Colors::green(std::cerr);
        std::cerr << "BUILDING MODULE [line: " << entry.line << "]\n";
        Colors::normal(std::cerr);
      } else if (auto* reg = std::get_if<Register>(&entry.cmd)) {
        Colors::green(std::cerr);
        std::cerr << "REGISTER MODULE INSTANCE AS \"" << reg->name
                  << "\"  [line: " << entry.line << "]\n";
        Colors::normal(std::cerr);
      } else {
        Colors::green(std::cerr);
        std::cerr << "CHECKING [line: " << entry.line << "]\n";
        Colors::normal(std::cerr);
      }
      CHECK_ERR(runCommand(entry.cmd));
    }
    return Ok{};
  }

  Result<> runCommand(WASTCommand& cmd) {
    if (auto* mod = std::get_if<WASTModule>(&cmd)) {
      return addModule(*mod);
    } else if (auto* reg = std::get_if<Register>(&cmd)) {
      return addRegistration(*reg);
    } else if (auto* act = std::get_if<Action>(&cmd)) {
      doAction(*act);
      return Ok{};
    } else if (auto* assn = std::get_if<Assertion>(&cmd)) {
      return doAssertion(*assn);
    } else if (auto* instantiateModule =
                 std::get_if<ModuleInstantiation>(&cmd)) {
      return doInstantiate(*instantiateModule);
    } else {
      WASM_UNREACHABLE("unexpected command");
    }
  }

  Result<std::shared_ptr<Module>> makeModule(WASTModule& mod) {
    std::shared_ptr<Module> wasm;
    if (auto* quoted = std::get_if<QuotedModule>(&mod.module)) {
      wasm = std::make_shared<Module>();
      switch (quoted->type) {
        case QuotedModuleType::Text: {
          CHECK_ERR(parseModule(*wasm, quoted->module));
          break;
        }
        case QuotedModuleType::Binary: {
          std::vector<char> buffer(quoted->module.begin(),
                                   quoted->module.end());
          WasmBinaryReader reader(*wasm, FeatureSet::All, buffer);
          try {
            reader.read();
          } catch (ParseException& p) {
            std::stringstream ss;
            p.dump(ss);
            return Err{ss.str()};
          }
          break;
        }
      }
    } else if (auto* ptr = std::get_if<std::shared_ptr<Module>>(&mod.module)) {
      wasm = *ptr;
    } else {
      WASM_UNREACHABLE("unexpected module kind");
    }
    wasm->features = FeatureSet::All;
    return wasm;
  }

  Result<> validateModule(Module& wasm) {
    if (!WasmValidator().validate(wasm)) {
      return Err{"failed validation"};
    }
    return Ok{};
  }

  Result<> doInstantiate(ModuleInstantiation& instantiateModule) {
    auto moduleDefinitionName = instantiateModule.moduleName
                                  ? instantiateModule.moduleName
                                  : lastModuleDefinition;
    if (!moduleDefinitionName) {
      return Err{"No module definition found in module instantiation, and no "
                 "previous module definition was found."};
    }

    auto instanceName = instantiateModule.instanceName
                          ? instantiateModule.instanceName
                          : lastModuleDefinition;
    if (!instanceName) {
      return Err{"No instance name found in module instantiation, and no "
                 "previous module definition was found."};
    }

    return instantiate(*modules[*moduleDefinitionName], *instanceName);
  }

  Result<> instantiate(Module& wasm, Name instanceName) {
    std::shared_ptr<ShellExternalInterface> interface;
    std::shared_ptr<ModuleRunner> instance;
    try {
      interface = std::make_shared<ShellExternalInterface>(linkedInstances);
      instance =
        std::make_shared<ModuleRunner>(wasm, interface.get(), linkedInstances);

      // This is not an optimization: we want to execute anything, even relaxed
      // SIMD instructions.
      instance->setRelaxedBehavior(ModuleRunner::RelaxedBehavior::Execute);
      instance->instantiate();
    } catch (...) {
      return Err{"failed to instantiate module"};
    }

    lastInstance = instanceName;

    interfaces[instanceName] = std::move(interface);
    instances[instanceName] = std::move(instance);
    return Ok{};
  }

  Result<> addModule(WASTModule& mod) {
    auto module = makeModule(mod);
    CHECK_ERR(module);

    auto wasm = *module;
    CHECK_ERR(validateModule(*wasm));

    modules[wasm->name] = wasm;
    if (!mod.isDefinition) {
      CHECK_ERR(instantiate(*wasm, wasm->name));
    } else {
      lastModuleDefinition = wasm->name;
    }

    return Ok{};
  }

  Result<> addRegistration(Register& reg) {
    Name instanceName = reg.instanceName ? *reg.instanceName : lastInstance;

    auto instance = instances[instanceName];
    if (!instance) {
      return Err{"register called without a module"};
    }
    linkedInstances[reg.name] = instance;

    // We copy pointers as a registered module's name might still be used
    // in an assertion or invoke command.
    interfaces[reg.name] = interfaces[instanceName];
    instances[reg.name] = instances[instanceName];
    return Ok{};
  }

  struct TrapResult {};
  struct HostLimitResult {};
  struct ExceptionResult {};
  struct SuspensionResult {};
  using ActionResult = std::variant<Literals,
                                    TrapResult,
                                    HostLimitResult,
                                    ExceptionResult,
                                    SuspensionResult>;

  std::string resultToString(ActionResult& result) {
    if (std::get_if<TrapResult>(&result)) {
      return "trap";
    } else if (std::get_if<HostLimitResult>(&result)) {
      return "exceeded host limit";
    } else if (std::get_if<ExceptionResult>(&result)) {
      return "exception";
    } else if (std::get_if<SuspensionResult>(&result)) {
      return "suspension";
    } else if (auto* vals = std::get_if<Literals>(&result)) {
      std::stringstream ss;
      ss << *vals;
      return ss.str();
    } else {
      WASM_UNREACHABLE("unexpected result");
    }
  }

  ActionResult doAction(Action& act) {
    assert(instances[lastInstance].get());
    if (auto* invoke = std::get_if<InvokeAction>(&act)) {
      auto it = instances.find(invoke->base ? *invoke->base : lastInstance);
      if (it == instances.end()) {
        return TrapResult{};
      }
      auto& instance = it->second;
      Flow flow;
      try {
        flow = instance->callExport(invoke->name, invoke->args);
      } catch (TrapException&) {
        return TrapResult{};
      } catch (HostLimitException&) {
        return HostLimitResult{};
      } catch (WasmException&) {
        return ExceptionResult{};
      } catch (...) {
        WASM_UNREACHABLE("unexpected error");
      }
      if (flow.suspendTag) {
        // This is an unhandled suspension. Handle it here - clear the
        // suspension state - so nothing else is affected.
        instance->clearContinuationStore();
        return SuspensionResult{};
      }
      return flow.values;
    } else if (auto* get = std::get_if<GetAction>(&act)) {
      auto it = instances.find(get->base ? *get->base : lastInstance);
      if (it == instances.end()) {
        return TrapResult{};
      }
      auto& instance = it->second;
      try {
        return instance->getExportedGlobal(get->name);
      } catch (TrapException&) {
        return TrapResult{};
      } catch (...) {
        WASM_UNREACHABLE("unexpected error");
      }
    } else {
      WASM_UNREACHABLE("unexpected action");
    }
  }

  Result<> doAssertion(Assertion& assn) {
    if (auto* ret = std::get_if<AssertReturn>(&assn)) {
      return assertReturn(*ret);
    } else if (auto* act = std::get_if<AssertAction>(&assn)) {
      return assertAction(*act);
    } else if (auto* mod = std::get_if<AssertModule>(&assn)) {
      return assertModule(*mod);
    } else {
      WASM_UNREACHABLE("unexpected assertion");
    }
  }

  Result<> checkNaN(Literal val, NaNResult nan) {
    std::stringstream err;
    switch (nan.kind) {
      case NaNKind::Canonical:
        if (val.type != nan.type || !val.isCanonicalNaN()) {
          err << "expected canonical " << nan.type << " NaN, got " << val;
          return Err{err.str()};
        }
        break;
      case NaNKind::Arithmetic:
        if (val.type != nan.type || !val.isArithmeticNaN()) {
          err << "expected arithmetic " << nan.type << " NaN, got " << val;
          return Err{err.str()};
        }
        break;
    }
    return Ok{};
  }

  Result<> checkLane(Literal val, LaneResult expected, Index index) {
    std::stringstream err;
    if (auto* e = std::get_if<Literal>(&expected)) {
      if (*e != val) {
        err << "expected " << *e << ", got " << val << " at lane " << index;
        return Err{err.str()};
      }
    } else if (auto* nan = std::get_if<NaNResult>(&expected)) {
      auto check = checkNaN(val, *nan);
      if (auto* e = check.getErr()) {
        err << e->msg << " at lane " << index;
        return Err{err.str()};
      }
    } else {
      WASM_UNREACHABLE("unexpected lane expectation");
    }
    return Ok{};
  }

  Result<> assertReturn(AssertReturn& assn) {
    std::stringstream err;
    auto result = doAction(assn.action);
    auto* values = std::get_if<Literals>(&result);
    if (!values) {
      return Err{std::string("expected return, got ") + resultToString(result)};
    }
    if (values->size() != assn.expected.size()) {
      err << "expected " << assn.expected.size() << " values, got "
          << resultToString(result);
      return Err{err.str()};
    }
    for (Index i = 0; i < values->size(); ++i) {
      auto atIndex = [&]() {
        if (values->size() <= 1) {
          return std::string{};
        }
        std::stringstream ss;
        ss << " at index " << i;
        return ss.str();
      };

      Literal val = (*values)[i];
      auto& expected = assn.expected[i];
      if (auto* v = std::get_if<Literal>(&expected)) {
        if (val != *v) {
          err << "expected " << *v << ", got " << val << atIndex();
          return Err{err.str()};
        }
      } else if (auto* ref = std::get_if<RefResult>(&expected)) {
        if (!val.type.isRef() ||
            !HeapType::isSubType(val.type.getHeapType(), ref->type)) {
          err << "expected " << ref->type << " reference, got " << val
              << atIndex();
          return Err{err.str()};
        }
      } else if (auto* nan = std::get_if<NaNResult>(&expected)) {
        auto check = checkNaN(val, *nan);
        if (auto* e = check.getErr()) {
          err << e->msg << atIndex();
          return Err{err.str()};
        }
      } else if (auto* lanes = std::get_if<LaneResults>(&expected)) {
        switch (lanes->size()) {
          case 4: {
            auto vals = val.getLanesF32x4();
            for (Index i = 0; i < 4; ++i) {
              auto check = checkLane(vals[i], (*lanes)[i], i);
              if (auto* e = check.getErr()) {
                err << e->msg << atIndex();
                return Err{err.str()};
              }
            }
            break;
          }
          case 2: {
            auto vals = val.getLanesF64x2();
            for (Index i = 0; i < 2; ++i) {
              auto check = checkLane(vals[i], (*lanes)[i], i);
              if (auto* e = check.getErr()) {
                err << e->msg << atIndex();
                return Err{err.str()};
              }
            }
            break;
          }
          default:
            WASM_UNREACHABLE("unexpected number of lanes");
        }
      } else {
        WASM_UNREACHABLE("unexpected expectation");
      }
    }
    return Ok{};
  }

  Result<> assertAction(AssertAction& assn) {
    std::stringstream err;
    auto result = doAction(assn.action);
    switch (assn.type) {
      case ActionAssertionType::Trap:
        if (std::get_if<TrapResult>(&result)) {
          return Ok{};
        }
        err << "expected trap";
        break;
      case ActionAssertionType::Exhaustion:
        if (std::get_if<HostLimitResult>(&result)) {
          return Ok{};
        }
        err << "expected exhaustion";
        break;
      case ActionAssertionType::Exception:
        if (std::get_if<ExceptionResult>(&result)) {
          return Ok{};
        }
        err << "expected exception";
        break;
      case ActionAssertionType::Suspension:
        if (std::get_if<SuspensionResult>(&result)) {
          return Ok{};
        }
        err << "expected suspension";
        break;
    }
    err << ", got " << resultToString(result);
    return Err{err.str()};
  }

  Result<> assertModule(AssertModule& assn) {
    auto wasm = makeModule(assn.wasm);
    if (const auto* err = wasm.getErr()) {
      if (assn.type == ModuleAssertionType::Malformed ||
          assn.type == ModuleAssertionType::Invalid) {
        return Ok{};
      }
      return Err{err->msg};
    }

    if (assn.type == ModuleAssertionType::Malformed) {
      return Err{"expected malformed module"};
    }

    auto valid = validateModule(**wasm);
    if (auto* err = valid.getErr()) {
      if (assn.type == ModuleAssertionType::Invalid) {
        return Ok{};
      }
      return Err{err->msg};
    }

    if (assn.type == ModuleAssertionType::Invalid) {
      return Err{"expected invalid module"};
    }

    auto instance = instantiate(**wasm, (*wasm)->name);
    if (auto* err = instance.getErr()) {
      if (assn.type == ModuleAssertionType::Unlinkable ||
          assn.type == ModuleAssertionType::Trap) {
        return Ok{};
      }
      return Err{err->msg};
    }

    if (assn.type == ModuleAssertionType::Unlinkable) {
      return Err{"expected unlinkable module"};
    }
    if (assn.type == ModuleAssertionType::Trap) {
      return Err{"expected instantiation to trap"};
    }

    WASM_UNREACHABLE("unexpected module assertion");
  }

  // spectest module is a default host-provided module defined by the spec's
  // reference interpreter. It's been replaced by the `(register ...)`
  // mechanism in the recent spec tests, and is kept for legacy tests only.
  //
  // TODO: spectest module is considered deprecated by the spec. Remove when
  // is actually removed from the spec test.
  void buildSpectestModule() {
    auto spectest = std::make_shared<Module>();
    spectest->features = FeatureSet::All;
    Builder builder(*spectest);

    spectest->addGlobal(builder.makeGlobal(Name::fromInt(0),
                                           Type::i32,
                                           builder.makeConst<uint32_t>(666),
                                           Builder::Immutable));
    spectest->addGlobal(builder.makeGlobal(Name::fromInt(1),
                                           Type::i64,
                                           builder.makeConst<uint64_t>(666),
                                           Builder::Immutable));
    spectest->addGlobal(builder.makeGlobal(Name::fromInt(2),
                                           Type::f32,
                                           builder.makeConst<float>(666.6f),
                                           Builder::Immutable));
    spectest->addGlobal(builder.makeGlobal(Name::fromInt(3),
                                           Type::f64,
                                           builder.makeConst<double>(666.6),
                                           Builder::Immutable));
    spectest->addExport(
      builder.makeExport("global_i32", Name::fromInt(0), ExternalKind::Global));
    spectest->addExport(
      builder.makeExport("global_i64", Name::fromInt(1), ExternalKind::Global));
    spectest->addExport(
      builder.makeExport("global_f32", Name::fromInt(2), ExternalKind::Global));
    spectest->addExport(
      builder.makeExport("global_f64", Name::fromInt(3), ExternalKind::Global));

    spectest->addTable(builder.makeTable(
      Name::fromInt(0), Type(HeapType::func, Nullable), 10, 20));
    spectest->addExport(
      builder.makeExport("table", Name::fromInt(0), ExternalKind::Table));

    spectest->addTable(builder.makeTable(
      Name::fromInt(1), Type(HeapType::func, Nullable), 10, 20, Type::i64));
    spectest->addExport(
      builder.makeExport("table64", Name::fromInt(1), ExternalKind::Table));

    Memory* memory =
      spectest->addMemory(builder.makeMemory(Name::fromInt(0), 1, 2));
    spectest->addExport(
      builder.makeExport("memory", memory->name, ExternalKind::Memory));

    // print_* functions are handled separately, no need to define here.

    WASTModule mod = {/*isDefinition=*/false, spectest};
    auto added = addModule(mod);
    if (added.getErr()) {
      WASM_UNREACHABLE("error building spectest module");
    }
    Register registration{/*name=*/"spectest"};
    modules["spectest"] = spectest;
    auto registered = addRegistration(registration);
    if (registered.getErr()) {
      WASM_UNREACHABLE((std::string("error registering spectest module: ") +
                        registered.getErr()->msg)
                         .c_str());
    }
  }
};

int main(int argc, const char* argv[]) {
  Name entry;
  std::set<size_t> skipped;

  // Read stdin by default.
  std::string infile = "-";
  Options options("wasm-shell", "Execute .wast files");
  options.add_positional(
    "INFILE",
    Options::Arguments::One,
    [&](Options* o, const std::string& argument) { infile = argument; });
  options.parse(argc, argv);

  auto input = read_file<std::string>(infile, Flags::Text);

  // Check that we can parse the script correctly with the new parser.
  auto script = WATParser::parseScript(input);
  if (auto* err = script.getErr()) {
    std::cerr << err->msg << '\n';
    exit(1);
  }

  Lexer lexer(input);
  auto result = Shell(options).run(*script);
  if (auto* err = result.getErr()) {
    std::cerr << err->msg << '\n';
    exit(1);
  }

  Colors::green(std::cerr);
  Colors::bold(std::cerr);
  std::cerr << "all checks passed.\n";
  Colors::normal(std::cerr);
}
