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

//
// Emit a C  wrapper file that can run the wasm after it is compiled with
// wasm2c, useful for fuzzing.
//

#include <sstream>
#include <string>

#include "wasm.h"

namespace wasm {

// Mangle a name in (hopefully) exactly the same way wasm2c does.
inline std::string wasm2cMangle(Name name, Signature sig) {
  const char escapePrefix = 'Z';
  std::string mangled = "Z_";
  const char* original = name.str;
  unsigned char c;
  while ((c = *original++)) {
    if ((isalnum(c) && c != escapePrefix) || c == '_') {
      // This character is ok to emit as it is.
      mangled += c;
    } else {
      // This must be escaped, as prefix + hex character code.
      mangled += escapePrefix;
      std::stringstream ss;
      ss << std::hex << std::uppercase << unsigned(c);
      mangled += ss.str();
    }
  }

  // Emit the result and params.
  mangled += "Z_";

  auto wasm2cSignature = [](Type type) {
    TODO_SINGLE_COMPOUND(type);
    switch (type.getBasic()) {
      case Type::none:
        return 'v';
      case Type::i32:
        return 'i';
      case Type::i64:
        return 'j';
      case Type::f32:
        return 'f';
      case Type::f64:
        return 'd';
      default:
        Fatal() << "unhandled wasm2c wrapper signature type: " << type;
    }
  };

  mangled += wasm2cSignature(sig.results);
  if (sig.params.isTuple()) {
    for (const auto& param : sig.params) {
      mangled += wasm2cSignature(param);
    }
  } else {
    mangled += wasm2cSignature(sig.params);
  }

  return mangled;
}

inline std::string generateWasm2CWrapper(Module& wasm) {
  // First, emit implementations of the wasm's imports so that the wasm2c code
  // can call them. The names use wasm2c's name mangling.
  std::string ret = R"(
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

#include "wasm-rt-impl.h"
#include "wasm.h"

void _Z_fuzzingZ2DsupportZ_logZ2Di32Z_vi(u32 x) {
  printf("[LoggingExternalInterface logging %d]\n", x);
}
void (*Z_fuzzingZ2DsupportZ_logZ2Di32Z_vi)(u32) = _Z_fuzzingZ2DsupportZ_logZ2Di32Z_vi;

void _Z_fuzzingZ2DsupportZ_logZ2Di64Z_vj(u64 x) {
  printf("[LoggingExternalInterface logging %" PRId64 "]\n", (int64_t)x);
}
void (*Z_fuzzingZ2DsupportZ_logZ2Di64Z_vj)(u64) = _Z_fuzzingZ2DsupportZ_logZ2Di64Z_vj;

void _Z_fuzzingZ2DsupportZ_logZ2Di64Z_vii(u32 x, u32 y) {
  printf("[LoggingExternalInterface logging %d %d]\n", x, y);
}
void (*Z_fuzzingZ2DsupportZ_logZ2Di64Z_vii)(u32, u32) = _Z_fuzzingZ2DsupportZ_logZ2Di64Z_vii;

void _Z_fuzzingZ2DsupportZ_logZ2Df32Z_vf(f32 x) {
  printf("[LoggingExternalInterface logging %.17e]\n", x);
}
void (*Z_fuzzingZ2DsupportZ_logZ2Df32Z_vf)(f32) = _Z_fuzzingZ2DsupportZ_logZ2Df32Z_vf;

void _Z_fuzzingZ2DsupportZ_logZ2Df64Z_vd(f64 x) {
  printf("[LoggingExternalInterface logging %.17le]\n", x);
}
void (*Z_fuzzingZ2DsupportZ_logZ2Df64Z_vd)(f64) = _Z_fuzzingZ2DsupportZ_logZ2Df64Z_vd;

// Miscellaneous imports

u32 tempRet0 = 0;

void _Z_envZ_setTempRet0Z_vi(u32 x) {
  tempRet0 = x;
}
void (*Z_envZ_setTempRet0Z_vi)(u32) = _Z_envZ_setTempRet0Z_vi;

u32 _Z_envZ_getTempRet0Z_iv(void) {
  return tempRet0;
}
u32 (*Z_envZ_getTempRet0Z_iv)(void) = _Z_envZ_getTempRet0Z_iv;

// Main

int main(int argc, char** argv) {
  init();

  // We go through each export and call it, in turn. Note that we use a loop
  // so we can do all this with a single setjmp. A setjmp is needed to handle
  // wasm traps, and emitting a single one helps compilation speed into wasm as
  // compile times are O(size * num_setjmps).
  for (size_t curr = 0;; curr++) {
  )";
  if (wasm.getExportOrNull("hangLimitInitializer")) {
    ret += R"(
    // If present, call the hang limit initializer before each export.
    (*Z_hangLimitInitializerZ_vv)();
)";
  }
  ret += R"(
    // Prepare to call the export, so we can catch traps.
    if (WASM_RT_SETJMP(g_jmp_buf) != 0) {
      puts("exception!");
    } else {
      // Call the proper export.
      switch(curr) {
)";

  // For each function export in the wasm, emit code to call it and log its
  // result, similar to the other wrappers.
  size_t functionExportIndex = 0;

  for (auto& exp : wasm.exports) {
    if (exp->kind != ExternalKind::Function) {
      continue;
    }

    ret += "        case " + std::to_string(functionExportIndex++) + ":\n";

    auto* func = wasm.getFunction(exp->value);

    ret += std::string("          puts(\"[fuzz-exec] calling ") +
           exp->name.str + "\");\n";
    auto result = func->getResults();

    // Emit the call itself.
    ret += "            ";
    if (result != Type::none) {
      ret += std::string("printf(\"[fuzz-exec] note result: ") + exp->name.str +
             " => ";
      TODO_SINGLE_COMPOUND(result);
      switch (result.getBasic()) {
        case Type::i32:
          ret += "%d\\n\", ";
          break;
        case Type::i64:
          ret += "%\" PRId64 \"\\n\", (int64_t)";
          break;
        case Type::f32:
          ret += "%.17e\\n\", ";
          break;
        case Type::f64:
          ret += "%.17le\\n\", ";
          break;
        default:
          Fatal() << "unhandled wasm2c wrapper result type: " << result;
      }
    }

    // Call the export.
    ret += "(*";

    // Emit the callee's name with wasm2c name mangling.
    ret += wasm2cMangle(exp->name, func->getSig());

    ret += ")(";

    // Emit the parameters (all 0s, like the other wrappers).
    bool first = true;
    for (const auto& param : func->getParams()) {
      WASM_UNUSED(param);
      if (!first) {
        ret += ", ";
      }
      ret += "0";
      first = false;
    }
    if (result != Type::none) {
      ret += ")";
    }
    ret += ");\n";

    // Break from the big switch.
    ret += "          break;\n";
  }

  ret += R"(        default:
          return 0; // All done.
      }
    }
  }
  return 0;
}
)";

  return ret;
}

} // namespace wasm
