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

#ifndef parser_wat_parser_h
#define parser_wat_parser_h

#include <string_view>

#include "parser/lexer.h"
#include "support/result.h"
#include "wasm.h"

namespace wasm::WATParser {

// Parse a single WAT module.
Result<> parseModule(Module& wasm,
                     std::string_view in,
                     std::optional<std::string> filename = std::nullopt);

// Parse a single WAT module that may have other things after it, as in a wast
// file.
Result<> parseModule(Module& wasm, Lexer& lexer);

// Similar to `parseModule`, parse the fields of a single WAT module (after the
// initial module definition including its name) and stop at the ending right
// paren.
Result<> parseModuleBody(Module& wasm, Lexer& lexer);

Result<Literal> parseConst(Lexer& lexer);

struct InvokeAction {
  std::optional<Name> base;
  Name name;
  Literals args;
};

struct GetAction {
  std::optional<Name> base;
  Name name;
};

using Action = std::variant<InvokeAction, GetAction>;

struct RefResult {
  HeapType type;
};

struct NullRefResult {};

enum class NaNKind { Canonical, Arithmetic };

struct NaNResult {
  NaNKind kind;
  Type type;
};

using LaneResult = std::variant<Literal, NaNResult>;

using LaneResults = std::vector<LaneResult>;

using ExpectedResult =
  std::variant<Literal, NullRefResult, RefResult, NaNResult, LaneResults>;

using ExpectedResults = std::vector<ExpectedResult>;

struct AssertReturn {
  Action action;
  ExpectedResults expected;
};

enum class ActionAssertionType { Trap, Exhaustion, Exception, Suspension };

struct AssertAction {
  ActionAssertionType type;
  Action action;
};

enum class QuotedModuleType { Text, Binary };

struct QuotedModule {
  QuotedModuleType type;
  std::string module;
};

struct WASTModule {
  bool isDefinition = false;
  std::variant<QuotedModule, std::shared_ptr<Module>> module;
};

enum class ModuleAssertionType { Trap, Malformed, Invalid, Unlinkable };

struct AssertModule {
  ModuleAssertionType type;
  WASTModule wasm;
};

using Assertion = std::variant<AssertReturn, AssertAction, AssertModule>;

struct Register {
  // TODO: Rename this to distinguish it from instanceName.
  Name name;
  std::optional<Name> instanceName = std::nullopt;
};

struct ModuleInstantiation {
  // If not specified, instantiate the most recent module definition.
  std::optional<Name> moduleName;

  // If not specified, use the moduleName
  std::optional<Name> instanceName;
};

using WASTCommand =
  std::variant<WASTModule, Register, Action, Assertion, ModuleInstantiation>;

struct ScriptEntry {
  WASTCommand cmd;
  size_t line;
};

using WASTScript = std::vector<ScriptEntry>;

Result<WASTScript> parseScript(std::string_view in);

} // namespace wasm::WATParser

#endif // parser_wat_parser_h
