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

#include "src/decompiler.h"

#include "src/decompiler-ast.h"
#include "src/decompiler-ls.h"
#include "src/decompiler-naming.h"

#include "src/stream.h"

#define WABT_TRACING 0
#include "src/tracing.h"

#include <inttypes.h>

namespace wabt {

struct Decompiler {
  Decompiler(const Module& module, const DecompileOptions& options)
      : mc(module), options(options) {}

  // Sorted such that "greater precedence" is also the bigger enum val.
  enum Precedence {
    // Low precedence.
    None,      // precedence doesn't matter, since never nested.
    Assign,    // =
    OtherBin,  // min
    Bit,       // & |
    Equal,     // == != < > >= <=
    Shift,     // << >>
    Add,       // + -
    Multiply,  // * / %
    If,        // if{}
    Indexing,  // []
    Atomic,    // (), a, 1, a()
    // High precedence.
  };

  // Anything besides these will get parentheses if used with equal precedence,
  // for clarity.
  bool Associative(Precedence p) {
    return p == Precedence::Add || p == Precedence::Multiply;
  }

  struct Value {
    std::vector<std::string> v;
    // Lazily add bracketing only if the parent requires it.
    // This is the precedence level of this value, for example, if this
    // precedence is Add, and the parent is Multiply, bracketing is needed,
    // but not if it is the reverse.
    Precedence precedence;

    Value(std::vector<std::string>&& v, Precedence p)
      : v(v), precedence(p) {}

    size_t width() {
      size_t w = 0;
      for (auto &s : v) {
        w = std::max(w, s.size());
      }
      return w;
    }

    // This value should really never be copied, only moved.
    Value(Value&& rhs) = default;
    Value(const Value& rhs) = delete;
    Value& operator=(Value&& rhs) = default;
    Value& operator=(const Value& rhs) = delete;
  };

  std::string to_string(double d) {
    auto s = std::to_string(d);
    // Remove redundant trailing '0's that to_string produces.
    while (s.size() > 2 && s.back() == '0' && s[s.size() - 2] != '.')
      s.pop_back();
    return s;
  }

  std::string Indent(size_t amount) {
    return std::string(amount, ' ');
  }

  std::string OpcodeToToken(Opcode opcode) {
    std::string s = opcode.GetDecomp();
    std::replace(s.begin(), s.end(), '.', '_');
    return s;
  }

  void IndentValue(Value &val, size_t amount, string_view first_indent) {
    auto indent = Indent(amount);
    for (auto& stat : val.v) {
      auto is = (&stat != &val.v[0] || first_indent.empty())
                    ? string_view(indent)
                    : first_indent;
      stat.insert(0, is.data(), is.size());
    }
  }

  Value WrapChild(Value &child, string_view prefix, string_view postfix,
                  Precedence precedence) {
    auto width = prefix.size() + postfix.size() + child.width();
    auto &v = child.v;
    if (width < target_exp_width ||
        (prefix.size() <= indent_amount && postfix.size() <= indent_amount)) {
      if (v.size() == 1) {
        // Fits in a single line.
        v[0].insert(0, prefix.data(), prefix.size());
        v[0].append(postfix.data(), postfix.size());
      } else {
        // Multiline, but with prefix on same line.
        IndentValue(child, prefix.size(), prefix);
        v.back().append(postfix.data(), postfix.size());
      }
    } else {
      // Multiline with prefix on its own line.
      IndentValue(child, indent_amount, {});
      v.insert(v.begin(), std::string(prefix));
      v.back().append(postfix.data(), postfix.size());
    }
    child.precedence = precedence;
    return std::move(child);
  }

  void BracketIfNeeded(Value &val, Precedence parent_precedence) {
    if (parent_precedence < val.precedence ||
        (parent_precedence == val.precedence &&
         Associative(parent_precedence))) return;
    val = WrapChild(val, "(", ")", Precedence::Atomic);
  }

  Value WrapBinary(std::vector<Value>& args, string_view infix,
                   bool indent_right, Precedence precedence) {
    assert(args.size() == 2);
    auto& left = args[0];
    auto& right = args[1];
    BracketIfNeeded(left, precedence);
    BracketIfNeeded(right, precedence);
    auto width = infix.size() + left.width() + right.width() + 2;
    if (width < target_exp_width && left.v.size() == 1 && right.v.size() == 1) {
      return Value{{cat(left.v[0], " ", infix, " ", right.v[0])}, precedence};
    } else {
      Value bin { {}, precedence };
      std::move(left.v.begin(), left.v.end(), std::back_inserter(bin.v));
      bin.v.back().append(" ", 1);
      bin.v.back().append(infix.data(), infix.size());
      if (indent_right) IndentValue(right, indent_amount, {});
      std::move(right.v.begin(), right.v.end(), std::back_inserter(bin.v));
      return bin;
    }
  }

  Value WrapNAry(std::vector<Value>& args, string_view prefix,
                 string_view postfix, Precedence precedence) {
    size_t total_width = 0;
    size_t max_width = 0;
    bool multiline = false;
    for (auto& child : args) {
      auto w = child.width();
      max_width = std::max(max_width, w);
      total_width += w;
      multiline = multiline || child.v.size() > 1;
    }
    if (!multiline &&
        (total_width + prefix.size() + postfix.size() < target_exp_width ||
         args.empty())) {
      // Single line.
      auto s = std::string(prefix);
      for (auto& child : args) {
        if (&child != &args[0])
          s += ", ";
        s += child.v[0];
      }
      s += postfix;
      return Value{{std::move(s)}, precedence};
    } else {
      // Multi-line.
      Value ml { {}, precedence };
      auto ident_with_name = max_width + prefix.size() < target_exp_width;
      size_t i = 0;
      for (auto& child : args) {
        IndentValue(child, ident_with_name ? prefix.size() : indent_amount,
                    !i && ident_with_name ? prefix : string_view {});
        if (i < args.size() - 1) child.v.back() += ",";
        std::move(child.v.begin(), child.v.end(),
                  std::back_inserter(ml.v));
        i++;
      }
      if (!ident_with_name) ml.v.insert(ml.v.begin(), std::string(prefix));
      ml.v.back() += postfix;
      return ml;
    }
  }

  string_view VarName(string_view name) {
    assert(!name.empty());
    return name[0] == '$' ? name.substr(1) : name;
  }

  template<ExprType T> Value Get(const VarExpr<T>& ve) {
    return Value{{std::string(VarName(ve.var.name()))}, Precedence::Atomic};
  }

  template<ExprType T> Value Set(Value& child, const VarExpr<T>& ve) {
    return WrapChild(child, VarName(ve.var.name()) + " = ", "", Precedence::Assign);
  }

  std::string TempVarName(Index n) {
    // FIXME: this needs much better variable naming. Problem is, the code
    // in generate-names.cc has allready run, its dictionaries deleted, so it
    // is not easy to integrate with it.
    return "t" + std::to_string(n);
  }

  std::string LocalDecl(const std::string& name, Type t) {
    auto struc = lst.GenTypeDecl(name);
    return cat(VarName(name), ":",
               struc.empty() ? GetDecompTypeName(t) : struc);
  }

  bool ConstIntVal(const Expr* e, uint64_t &dest) {
    dest = 0;
    if (!e || e->type() != ExprType::Const) return false;
    auto& c = cast<ConstExpr>(e)->const_;
    if (c.type() != Type::I32 && c.type() != Type::I64) return false;
    dest = c.type() == Type::I32 ? c.u32() : c.u64();
    return true;
  }

  void LoadStore(Value &val, const Node& addr_exp, uint64_t offset,
                  Opcode opc, Address align, Type op_type) {
    bool append_type = true;
    auto access = lst.GenAccess(offset, addr_exp);
    if (!access.empty()) {
      if (access == "*") {
        // The variable was declared as a typed pointer, so this access
        // doesn't need a type.
        append_type = false;
      } else {
        // We can do this load/store as a struct access.
        BracketIfNeeded(val, Precedence::Indexing);
        val.v.back() += "." + access;
        return;
      }
    }
    // Detect absolute addressing, which we try to turn into references to the
    // data section when possible.
    uint64_t abs_base;
    if (ConstIntVal(addr_exp.e, abs_base)) {
      // We don't care what part of the absolute address was stored where,
      // 1[0] and 0[1] are the same.
      abs_base += offset;
      // FIXME: make this less expensive with a binary search or whatever.
      for (auto dat : mc.module.data_segments) {
        uint64_t dat_base;
        if (dat->offset.exprs.size() == 1 &&
            ConstIntVal(&dat->offset.exprs.front(), dat_base) &&
            abs_base >= dat_base &&
            abs_base < dat_base + dat->data.size()) {
          // We are inside the range of this data segment!
          // Turn expression into data_name[index]
          val = Value { { dat->name }, Precedence::Atomic };
          // The new offset is from the start of the data segment, instead of
          // whatever it was.. this may be a different value from both the
          // original const and offset!
          offset = abs_base - dat_base;
        }
      }
    }
    // Do the load/store as a generalized indexing operation.
    // The offset is divisible by the alignment in 99.99% of
    // cases, but the spec doesn't guarantee it, so we must
    // have a backup syntax.
    auto index = offset % align == 0
                ? std::to_string(offset / align)
                : cat(std::to_string(offset), "@", std::to_string(align));
    // Detect the very common case of (base + (index << 2))[0]:int etc.
    // so we can instead do base[index]:int
    // TODO: (index << 2) on the left of + occurs also.
    // TODO: sadly this does not address cases where the shift amount > align.
    // (which happens for arrays of structs or arrays of long (with align=4)).
    // TODO: also very common is (v = base + (index << 2))[0]:int
    if (addr_exp.etype == ExprType::Binary) {
      auto& pe = *cast<BinaryExpr>(addr_exp.e);
      auto& shift_exp = addr_exp.children[1];
      if (pe.opcode == Opcode::I32Add &&
          shift_exp.etype == ExprType::Binary) {
        auto& se = *cast<BinaryExpr>(shift_exp.e);
        auto& const_exp = shift_exp.children[1];
        if (se.opcode == Opcode::I32Shl &&
            const_exp.etype == ExprType::Const) {
          auto& ce = *cast<ConstExpr>(const_exp.e);
          if (ce.const_.type() == Type::I32 &&
              (1ULL << ce.const_.u32()) == align) {
            // Pfew, case detected :( Lets re-write this in Haskell.
            // TODO: we're decompiling these twice.
            // The thing to the left of << is going to be part of the index.
            auto ival = DecompileExpr(shift_exp.children[0], &shift_exp);
            if (ival.v.size() == 1) {  // Don't bother if huge.
              if (offset == 0) {
                index = ival.v[0];
              } else {
                BracketIfNeeded(ival, Precedence::Add);
                index = cat(ival.v[0], " + ", index);
              }
              // We're going to use the thing to the left of + as the new
              // base address:
              val = DecompileExpr(addr_exp.children[0], &addr_exp);
            }
          }
        }
      }
    }
    BracketIfNeeded(val, Precedence::Indexing);
    val.v.back() += cat("[", index, "]");
    if (append_type) {
      val.v.back() +=
        cat(":", GetDecompTypeName(GetMemoryType(op_type, opc)),
            lst.GenAlign(align, opc));
    }
    val.precedence = Precedence::Indexing;
  }

  Value DecompileExpr(const Node& n, const Node* parent) {
    std::vector<Value> args;
    for (auto& c : n.children) {
      args.push_back(DecompileExpr(c, &n));
    }
    // First deal with the specialized node types.
    switch (n.ntype) {
      case NodeType::FlushToVars: {
        std::string decls = "let ";
        for (Index i = 0; i < n.u.var_count; i++) {
          if (i) decls += ", ";
          decls += TempVarName(n.u.var_start + i);
        }
        decls += " = ";
        return WrapNAry(args, decls, "", Precedence::Assign);
      }
      case NodeType::FlushedVar: {
        return Value { { TempVarName(n.u.var_start) }, Precedence::Atomic };
      }
      case NodeType::Statements: {
        Value stats { {}, Precedence::None };
        for (size_t i = 0; i < n.children.size(); i++) {
          auto& s = args[i].v.back();
          if (s.back() != '}' && s.back() != ':') s += ';';
          std::move(args[i].v.begin(), args[i].v.end(),
                    std::back_inserter(stats.v));
        }
        return stats;
      }
      case NodeType::EndReturn: {
        return WrapNAry(args, "return ", "", Precedence::None);
      }
      case NodeType::Decl: {
        cur_ast->vars_defined[n.u.var->name()].defined = true;
        return Value{
            {"var " + LocalDecl(std::string(n.u.var->name()),
                                cur_func->GetLocalType(*n.u.var))},
            Precedence::None};
      }
      case NodeType::DeclInit: {
        if (cur_ast->vars_defined[n.u.var->name()].defined) {
          // This has already been pre-declared, output as assign.
          return WrapChild(args[0], cat(VarName(n.u.var->name()), " = "), "",
                           Precedence::None);
        } else {
          return WrapChild(
              args[0],
              cat("var ",
                  LocalDecl(std::string(n.u.var->name()),
                            cur_func->GetLocalType(*n.u.var)),
                  " = "),
              "", Precedence::None);
        }
      }
      case NodeType::Expr:
        // We're going to fall thru to the second switch to deal with ExprType.
        break;
      case NodeType::Uninitialized:
        assert(false);
        break;
    }
    // Existing ExprTypes.
    switch (n.etype) {
      case ExprType::Const: {
        auto& c = cast<ConstExpr>(n.e)->const_;
        switch (c.type()) {
          case Type::I32:
            return Value{{std::to_string(static_cast<int32_t>(c.u32()))},
                         Precedence::Atomic};
          case Type::I64:
            return Value{{std::to_string(static_cast<int64_t>(c.u64())) + "L"},
                         Precedence::Atomic};
          case Type::F32: {
            float f = Bitcast<float>(c.f32_bits());
            return Value{{to_string(f) + "f"}, Precedence::Atomic};
          }
          case Type::F64: {
            double d = Bitcast<double>(c.f64_bits());
            return Value{{to_string(d)}, Precedence::Atomic};
          }
          case Type::V128:
            return Value{{"V128"}, Precedence::Atomic};  // FIXME
          default:
            WABT_UNREACHABLE;
        }
      }
      case ExprType::LocalGet: {
        return Get(*cast<LocalGetExpr>(n.e));
      }
      case ExprType::GlobalGet: {
        return Get(*cast<GlobalGetExpr>(n.e));
      }
      case ExprType::LocalSet: {
        return Set(args[0], *cast<LocalSetExpr>(n.e));
      }
      case ExprType::GlobalSet: {
        return Set(args[0], *cast<GlobalSetExpr>(n.e));
      }
      case ExprType::LocalTee: {
        auto& te = *cast<LocalTeeExpr>(n.e);
        return args.empty() ? Get(te) : Set(args[0], te);
      }
      case ExprType::Binary: {
        auto& be = *cast<BinaryExpr>(n.e);
        auto opcs = OpcodeToToken(be.opcode);
        // TODO: Is this selection better done on Opcode values directly?
        // What if new values get added and OtherBin doesn't make sense?
        auto prec = Precedence::OtherBin;
        if (opcs == "*" || opcs == "/" || opcs == "%") {
          prec = Precedence::Multiply;
        } else if (opcs == "+" || opcs == "-") {
          prec = Precedence::Add;
        } else if (opcs == "&" || opcs == "|" || opcs == "^") {
          prec = Precedence::Bit;
        } else if (opcs == "<<" || opcs == ">>") {
          prec = Precedence::Shift;
        }
        return WrapBinary(args, opcs, false, prec);
      }
      case ExprType::Compare: {
        auto& ce = *cast<CompareExpr>(n.e);
        return WrapBinary(args, OpcodeToToken(ce.opcode), false,
                          Precedence::Equal);
      }
      case ExprType::Unary: {
        auto& ue = *cast<UnaryExpr>(n.e);
        //BracketIfNeeded(stack.back());
        // TODO: also version without () depending on precedence.
        return WrapChild(args[0], OpcodeToToken(ue.opcode) + "(", ")",
                         Precedence::Atomic);
      }
      case ExprType::Load: {
        auto& le = *cast<LoadExpr>(n.e);
        LoadStore(args[0], n.children[0], le.offset, le.opcode, le.align,
                  le.opcode.GetResultType());
        return std::move(args[0]);
      }
      case ExprType::Store: {
        auto& se = *cast<StoreExpr>(n.e);
        LoadStore(args[0], n.children[0], se.offset, se.opcode, se.align,
                  se.opcode.GetParamType2());
        return WrapBinary(args, "=", true, Precedence::Assign);
      }
      case ExprType::If: {
        auto ife = cast<IfExpr>(n.e);
        Value *elsep = nullptr;
        if (!ife->false_.empty()) {
          elsep = &args[2];
        }
        auto& thenp = args[1];
        auto& ifs = args[0];
        bool multiline = ifs.v.size() > 1 || thenp.v.size() > 1;
        size_t width = ifs.width() + thenp.width();
        if (elsep) {
          width += elsep->width();
          multiline = multiline || elsep->v.size() > 1;
        }
        multiline = multiline || width > target_exp_width;
        if (multiline) {
          auto if_start = string_view("if (");
          IndentValue(ifs, if_start.size(), if_start);
          ifs.v.back() += ") {";
          IndentValue(thenp, indent_amount, {});
          std::move(thenp.v.begin(), thenp.v.end(), std::back_inserter(ifs.v));
          if (elsep) {
            ifs.v.push_back("} else {");
            IndentValue(*elsep, indent_amount, {});
            std::move(elsep->v.begin(), elsep->v.end(), std::back_inserter(ifs.v));
          }
          ifs.v.push_back("}");
          ifs.precedence = Precedence::If;
          return std::move(ifs);
        } else {
          auto s = cat("if (", ifs.v[0], ") { ", thenp.v[0], " }");
          if (elsep)
            s += cat(" else { ", elsep->v[0], " }");
          return Value{{std::move(s)}, Precedence::If};
        }
      }
      case ExprType::Block: {
        auto& val = args[0];
        val.v.push_back(
              cat("label ", VarName(cast<BlockExpr>(n.e)->block.label), ":"));
        // If this block is part of a larger statement scope, it doesn't
        // need its own indenting, but if its part of an exp we wrap it in {}.
        if (parent && parent->ntype != NodeType::Statements
                   && parent->etype != ExprType::Block
                   && parent->etype != ExprType::Loop
                   && (parent->etype != ExprType::If ||
                       &parent->children[0] == &n)) {
          IndentValue(val, indent_amount, {});
          val.v.insert(val.v.begin(), "{");
          val.v.push_back("}");
        }
        val.precedence = Precedence::Atomic;
        return std::move(val);
      }
      case ExprType::Loop: {
        auto& val = args[0];
        auto& block = cast<LoopExpr>(n.e)->block;
        IndentValue(val, indent_amount, {});
        val.v.insert(val.v.begin(), cat("loop ", VarName(block.label), " {"));
        val.v.push_back("}");
        val.precedence = Precedence::Atomic;
        return std::move(val);
      }
      case ExprType::Br: {
        auto be = cast<BrExpr>(n.e);
        return Value{{(n.u.lt == LabelType::Loop ? "continue " : "goto ") +
                      VarName(be->var.name())},
                     Precedence::None};
      }
      case ExprType::BrIf: {
        auto bie = cast<BrIfExpr>(n.e);
        auto jmp = n.u.lt == LabelType::Loop ? "continue" : "goto";
        return WrapChild(args[0], "if (", cat(") ", jmp, " ",
                                              VarName(bie->var.name())),
                         Precedence::None);
      }
      case ExprType::Return: {
        return WrapNAry(args, "return ", "", Precedence::None);
      }
      case ExprType::Rethrow: {
        return WrapNAry(args, "rethrow ", "", Precedence::None);
      }
      case ExprType::Drop: {
        // Silent dropping of return values is very common, so currently
        // don't output this.
        return std::move(args[0]);
      }
      case ExprType::Nop: {
        return Value{{"nop"}, Precedence::None};
      }
      case ExprType::Unreachable: {
        return Value{{"unreachable"}, Precedence::None};
      }
      case ExprType::RefNull: {
        return Value{{"null"}, Precedence::Atomic};
      }
      case ExprType::BrTable: {
        auto bte = cast<BrTableExpr>(n.e);
        std::string ts = "br_table[";
        for (auto &v : bte->targets) {
          ts += VarName(v.name());
          ts += ", ";
        }
        ts += "..";
        ts += VarName(bte->default_target.name());
        ts += "](";
        return WrapChild(args[0], ts, ")", Precedence::Atomic);
      }
      default: {
        // Everything that looks like a function call.
        std::string name;
        auto precedence = Precedence::Atomic;
        switch (n.etype) {
          case ExprType::Call:
            name = cast<CallExpr>(n.e)->var.name();
            break;
          case ExprType::ReturnCall:
            name = "return_call " + cast<ReturnCallExpr>(n.e)->var.name();
            precedence = Precedence::None;
            break;
          case ExprType::Convert:
            name = std::string(OpcodeToToken(cast<ConvertExpr>(n.e)->opcode));
            break;
          case ExprType::Ternary:
            name = std::string(OpcodeToToken(cast<TernaryExpr>(n.e)->opcode));
            break;
          case ExprType::Select:
            // This one looks like it could be translated to "?:" style ternary,
            // but the arguments are NOT lazy, and side effects definitely do
            // occur in the branches. So it has no clear equivalent in C-syntax.
            // To emphasize that all args are being evaluated in order, we
            // leave it as a function call.
            name = "select_if";
            break;
          case ExprType::MemoryGrow:
            name = "memory_grow";
            break;
          case ExprType::MemorySize:
            name = "memory_size";
            break;
          case ExprType::MemoryCopy:
            name = "memory_copy";
            break;
          case ExprType::MemoryFill:
            name = "memory_fill";
            break;
          case ExprType::RefIsNull:
            name = "is_null";
            break;
          case ExprType::CallIndirect:
            name = "call_indirect";
            break;
          case ExprType::ReturnCallIndirect:
            name = "return_call call_indirect";
            break;
          default:
            name = GetExprTypeName(n.etype);
            break;
        }
        return WrapNAry(args, name + "(", ")", precedence);
      }
    }
  }

  bool CheckImportExport(std::string& s,
                         ExternalKind kind,
                         Index index,
                         string_view name) {
    // Figure out if this thing is imported, exported, or neither.
    auto is_import = mc.module.IsImport(kind, Var(index));
    // TODO: is this the best way to check for export?
    // FIXME: this doesn't work for functions that get renamed in some way,
    // as the export has the original name..
    auto xport = mc.module.GetExport(name);
    auto is_export = xport && xport->kind == kind;
    if (is_export)
      s += "export ";
    if (is_import)
      s += "import ";
    return is_import;
  }

  std::string InitExp(const ExprList &el) {
    assert(!el.empty());
    AST ast(mc, nullptr);
    ast.Construct(el, 1, 0, false);
    auto val = DecompileExpr(ast.exp_stack[0], nullptr);
    assert(ast.exp_stack.size() == 1 && val.v.size() == 1);
    return std::move(val.v[0]);
  }

  // FIXME: Merge with WatWriter::WriteQuotedData somehow.
  std::string BinaryToString(const std::vector<uint8_t> &in) {
    std::string s = "\"";
    size_t line_start = 0;
    static const char s_hexdigits[] = "0123456789abcdef";
    for (auto c : in) {
      if (c >= ' ' && c <= '~') {
        s += c;
      } else {
        s += '\\';
        s += s_hexdigits[c >> 4];
        s += s_hexdigits[c & 0xf];
      }
      if (s.size() - line_start > target_exp_width) {
        if (line_start == 0) {
          s = "  " + s;
        }
        s += "\"\n  ";
        line_start = s.size();
        s += "\"";
      }
    }
    s += '\"';
    return s;
  }

  std::string Decompile() {
    std::string s;
    // Memories.
    Index memory_index = 0;
    for (auto m : mc.module.memories) {
      auto is_import =
          CheckImportExport(s, ExternalKind::Memory, memory_index, m->name);
      s += cat("memory ", m->name);
      if (!is_import) {
        s += cat("(initial: ", std::to_string(m->page_limits.initial),
                 ", max: ", std::to_string(m->page_limits.max), ")");
      }
      s += ";\n";
      memory_index++;
    }
    if (!mc.module.memories.empty())
      s += "\n";

    // Globals.
    Index global_index = 0;
    for (auto g : mc.module.globals) {
      auto is_import =
          CheckImportExport(s, ExternalKind::Global, global_index, g->name);
      s += cat("global ", g->name, ":", GetDecompTypeName(g->type));
      if (!is_import) {
        s += cat(" = ", InitExp(g->init_expr.exprs));
      }
      s += ";\n";
      global_index++;
    }
    if (!mc.module.globals.empty())
      s += "\n";

    // Tables.
    Index table_index = 0;
    for (auto tab : mc.module.tables) {
      auto is_import =
          CheckImportExport(s, ExternalKind::Table, table_index, tab->name);
      s += cat("table ", tab->name, ":", GetDecompTypeName(tab->elem_type));
      if (!is_import) {
        s += cat("(min: ", std::to_string(tab->elem_limits.initial),
                 ", max: ", std::to_string(tab->elem_limits.max), ")");
      }
      s += ";\n";
      table_index++;
    }
    if (!mc.module.tables.empty())
      s += "\n";

    // Data.
    for (auto dat : mc.module.data_segments) {
      s += cat("data ", dat->name, "(offset: ", InitExp(dat->offset.exprs), ") =");
      auto ds = BinaryToString(dat->data);
      if (ds.size() > target_exp_width / 2) {
        s += "\n";
      } else {
        s += " ";
      }
      s += ds;
      s += ";\n";
    }
    if (!mc.module.data_segments.empty())
      s += "\n";

    // Code.
    Index func_index = 0;
    for (auto f : mc.module.funcs) {
      cur_func = f;
      auto is_import =
          CheckImportExport(s, ExternalKind::Func, func_index, f->name);
      AST ast(mc, f);
      cur_ast = &ast;
      if (!is_import) {
        ast.Construct(f->exprs, f->GetNumResults(), 0, true);
        lst.Track(ast.exp_stack[0]);
        lst.CheckLayouts();
      }
      s += cat("function ", f->name, "(");
      for (Index i = 0; i < f->GetNumParams(); i++) {
        if (i)
          s += ", ";
        auto t = f->GetParamType(i);
        auto name = "$" + IndexToAlphaName(i);
        s += LocalDecl(name, t);
      }
      s += ")";
      if (f->GetNumResults()) {
        if (f->GetNumResults() == 1) {
          s += cat(":", GetDecompTypeName(f->GetResultType(0)));
        } else {
          s += ":(";
          for (Index i = 0; i < f->GetNumResults(); i++) {
            if (i)
              s += ", ";
            s += GetDecompTypeName(f->GetResultType(i));
          }
          s += ")";
        }
      }
      if (is_import) {
        s += ";";
      } else {
        s += " {\n";
        auto val = DecompileExpr(ast.exp_stack[0], nullptr);
        IndentValue(val, indent_amount, {});
        for (auto& stat : val.v) {
          s += stat;
          s += "\n";
        }
        s += "}";
      }
      s += "\n\n";
      mc.EndFunc();
      lst.Clear();
      func_index++;
      cur_ast = nullptr;
      cur_func = nullptr;
    }
    return s;
  }

  ModuleContext mc;
  const DecompileOptions& options;
  size_t indent_amount = 2;
  size_t target_exp_width = 70;
  const Func* cur_func = nullptr;
  AST* cur_ast = nullptr;
  LoadStoreTracking lst;
};

std::string Decompile(const Module& module, const DecompileOptions& options) {
  Decompiler decompiler(module, options);
  return decompiler.Decompile();
}

}  // namespace wabt
