/*
 * 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 "pass.h"
#include "shell-interface.h"
#include "support/command-line.h"
#include "support/file.h"
#include "wasm-interpreter.h"
#include "wasm-s-parser.h"
#include "wasm-validator.h"

using namespace cashew;
using namespace wasm;

Name ASSERT_RETURN("assert_return");
Name ASSERT_TRAP("assert_trap");
Name ASSERT_INVALID("assert_invalid");
Name ASSERT_MALFORMED("assert_malformed");
Name ASSERT_UNLINKABLE("assert_unlinkable");
Name INVOKE("invoke");
Name GET("get");

//
// An operation on a module
//

struct Operation {
  ModuleInstance* instance;
  Name operation;
  Name name;
  LiteralList arguments;

  Operation(Element& element,
            ModuleInstance* instanceInit,
            SExpressionWasmBuilder& builder,
            std::map<Name, std::unique_ptr<ModuleInstance>>& instances)
    : instance(instanceInit) {
    operation = element[0]->str();
    Index i = 1;
    if (element.size() >= 3 && element[2]->isStr()) {
      // module also specified
      Name moduleName = element[i++]->str();
      instance = instances[moduleName].get();
    }
    name = element[i++]->str();
    for (size_t j = i; j < element.size(); j++) {
      Expression* argument = builder.parseExpression(*element[j]);
      arguments.push_back(getLiteralFromConstExpression(argument));
    }
  }

  Literals operate() {
    if (operation == INVOKE) {
      return instance->callExport(name, arguments);
    } else if (operation == GET) {
      return {instance->getExport(name)};
    } else {
      WASM_UNREACHABLE("unknown operation");
    }
  }
};

static void
run_asserts(Name moduleName,
            size_t* i,
            bool* checked,
            Module* wasm,
            Element* root,
            SExpressionWasmBuilder* builder,
            Name entry,
            std::map<Name, std::unique_ptr<ShellExternalInterface>>& interfaces,
            std::map<Name, std::unique_ptr<ModuleInstance>>& instances) {
  ModuleInstance* instance = nullptr;
  if (wasm) {
    // prefix make_unique to work around visual studio bugs
    auto tempInterface = wasm::make_unique<ShellExternalInterface>();
    auto tempInstance =
      wasm::make_unique<ModuleInstance>(*wasm, tempInterface.get());
    interfaces[moduleName].swap(tempInterface);
    instances[moduleName].swap(tempInstance);
    instance = instances[moduleName].get();
    if (entry.is()) {
      Function* function = wasm->getFunction(entry);
      if (!function) {
        std::cerr << "Unknown entry " << entry << std::endl;
      } else {
        LiteralList arguments;
        for (const auto& param : function->sig.params) {
          arguments.push_back(Literal(param));
        }
        try {
          instance->callExport(entry, arguments);
        } catch (ExitException&) {
        }
      }
    }
  }
  while (*i < root->size()) {
    Element& curr = *(*root)[*i];
    IString id = curr[0]->str();
    if (id == MODULE) {
      break;
    }
    *checked = true;
    Colors::red(std::cerr);
    std::cerr << *i << '/' << (root->size() - 1);
    Colors::green(std::cerr);
    std::cerr << " CHECKING: ";
    Colors::normal(std::cerr);
    std::cerr << curr;
    Colors::green(std::cerr);
    std::cerr << " [line: " << curr.line << "]\n";
    Colors::normal(std::cerr);
    if (id == ASSERT_INVALID || id == ASSERT_MALFORMED ||
        id == ASSERT_UNLINKABLE) {
      // a module invalidity test
      Module wasm;
      wasm.features = FeatureSet::All;
      bool invalid = false;
      std::unique_ptr<SExpressionWasmBuilder> builder;
      try {
        builder = std::unique_ptr<SExpressionWasmBuilder>(
          new SExpressionWasmBuilder(wasm, *curr[1], IRProfile::Normal));
      } catch (const ParseException&) {
        invalid = true;
      }
      if (!invalid) {
        // maybe parsed ok, but otherwise incorrect
        invalid = !WasmValidator().validate(wasm);
      }
      if (!invalid && id == ASSERT_UNLINKABLE) {
        // validate "instantiating" the mdoule
        auto reportUnknownImport = [&](Importable* import) {
          std::cerr << "unknown import: " << import->module << '.'
                    << import->base << '\n';
          invalid = true;
        };
        ModuleUtils::iterImportedGlobals(wasm, reportUnknownImport);
        ModuleUtils::iterImportedTables(wasm, reportUnknownImport);
        ModuleUtils::iterImportedFunctions(wasm, [&](Importable* import) {
          if (import->module == SPECTEST && import->base.startsWith(PRINT)) {
            // We can handle it.
          } else {
            reportUnknownImport(import);
          }
        });
        for (auto& segment : wasm.elementSegments) {
          for (auto name : segment->data) {
            // spec tests consider it illegal to use spectest.print in a table
            if (auto* import = wasm.getFunction(name)) {
              if (import->imported() && import->module == SPECTEST &&
                  import->base.startsWith(PRINT)) {
                std::cerr << "cannot put spectest.print in table\n";
                invalid = true;
              }
            }
          }
        }
        if (wasm.memory.imported()) {
          reportUnknownImport(&wasm.memory);
        }
      }
      if (!invalid) {
        Colors::red(std::cerr);
        std::cerr << "[should have been invalid]\n";
        Colors::normal(std::cerr);
        Fatal() << &wasm << '\n';
      }
    } else if (id == INVOKE) {
      assert(wasm);
      Operation operation(curr, instance, *builder, instances);
      operation.operate();
    } else if (wasm) { // if no wasm, we skipped the module
      // an invoke test
      bool trapped = false;
      WASM_UNUSED(trapped);
      Literals result;
      try {
        Operation operation(*curr[1], instance, *builder, instances);
        result = operation.operate();
      } catch (const TrapException&) {
        trapped = true;
      } catch (const WasmException& e) {
        std::cout << "[exception thrown: " << e << "]" << std::endl;
        trapped = true;
      }
      if (id == ASSERT_RETURN) {
        assert(!trapped);
        Literals expected;
        if (curr.size() >= 3) {
          expected =
            getLiteralsFromConstExpression(builder->parseExpression(*curr[2]));
        }
        std::cerr << "seen " << result << ", expected " << expected << '\n';
        if (expected != result) {
          Fatal() << "unexpected, should be identical\n";
        }
      }
      if (id == ASSERT_TRAP) {
        assert(trapped);
      }
    }
    *i += 1;
  }
}

//
// main
//

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

  Options options("wasm-shell", "Execute .wast files");
  options
    .add("--entry",
         "-e",
         "Call the entry point after parsing the module",
         Options::Arguments::One,
         [&entry](Options*, const std::string& argument) { entry = argument; })
    .add("--skip",
         "-s",
         "Skip input on certain lines (comma-separated-list)",
         Options::Arguments::One,
         [&skipped](Options*, const std::string& argument) {
           size_t i = 0;
           while (i < argument.size()) {
             auto ending = argument.find(',', i);
             if (ending == std::string::npos) {
               ending = argument.size();
             }
             auto sub = argument.substr(i, ending - i);
             skipped.insert(atoi(sub.c_str()));
             i = ending + 1;
           }
         })
    .add_positional("INFILE",
                    Options::Arguments::One,
                    [](Options* o, const std::string& argument) {
                      o->extra["infile"] = argument;
                    });
  options.parse(argc, argv);

  auto input(
    read_file<std::vector<char>>(options.extra["infile"], Flags::Text));

  bool checked = false;

  // Modules named in the file

  std::map<Name, std::unique_ptr<Module>> modules;
  std::map<Name, std::unique_ptr<SExpressionWasmBuilder>> builders;
  std::map<Name, std::unique_ptr<ShellExternalInterface>> interfaces;
  std::map<Name, std::unique_ptr<ModuleInstance>> instances;

  try {
    if (options.debug) {
      std::cerr << "parsing text to s-expressions...\n";
    }
    SExpressionParser parser(input.data());
    Element& root = *parser.root;

    // A .wast may have multiple modules, with some asserts after them
    size_t i = 0;
    while (i < root.size()) {
      Element& curr = *root[i];
      if (skipped.count(curr.line) > 0) {
        Colors::green(std::cerr);
        std::cerr << "SKIPPING [line: " << curr.line << "]\n";
        Colors::normal(std::cerr);
        i++;
        continue;
      }
      IString id = curr[0]->str();
      if (id == MODULE) {
        if (options.debug) {
          std::cerr << "parsing s-expressions to wasm...\n";
        }
        Colors::green(std::cerr);
        std::cerr << "BUILDING MODULE [line: " << curr.line << "]\n";
        Colors::normal(std::cerr);
        auto module = wasm::make_unique<Module>();
        auto builder = wasm::make_unique<SExpressionWasmBuilder>(
          *module, *root[i], IRProfile::Normal);
        auto moduleName = module->name;
        builders[moduleName].swap(builder);
        modules[moduleName].swap(module);
        i++;
        modules[moduleName]->features = FeatureSet::All;
        bool valid = WasmValidator().validate(*modules[moduleName]);
        if (!valid) {
          std::cout << *modules[moduleName] << '\n';
          Fatal() << "module failed to validate, see above";
        }
        run_asserts(moduleName,
                    &i,
                    &checked,
                    modules[moduleName].get(),
                    &root,
                    builders[moduleName].get(),
                    entry,
                    interfaces,
                    instances);
      } else {
        run_asserts(Name(),
                    &i,
                    &checked,
                    nullptr,
                    &root,
                    nullptr,
                    entry,
                    interfaces,
                    instances);
      }
    }
  } catch (ParseException& p) {
    p.dump(std::cerr);
    exit(1);
  }

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