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

//
// asm2wasm console tool
//

#include <exception>

#include "ir/trapping.h"
#include "optimization-options.h"
#include "support/colors.h"
#include "support/command-line.h"
#include "support/file.h"
#include "wasm-builder.h"
#include "wasm-io.h"
#include "wasm-printing.h"
#include "wasm-validator.h"

#include "asm2wasm.h"

using namespace cashew;
using namespace wasm;

int main(int argc, const char* argv[]) {
  bool legalizeJavaScriptFFI = true;
  TrapMode trapMode = TrapMode::JS;
  bool wasmOnly = false;
  std::string sourceMapFilename;
  std::string sourceMapUrl;
  std::string symbolMap;
  bool emitBinary = true;

  OptimizationOptions options("asm2wasm",
                              "Translate asm.js files to .wast files");
  options
    .add("--output",
         "-o",
         "Output file (stdout if not specified)",
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["output"] = argument;
           Colors::setEnabled(false);
         })
    .add(
      "--mapped-globals",
      "-n",
      "Mapped globals",
      Options::Arguments::One,
      [](Options* o, const std::string& argument) {
        std::cerr
          << "warning: the --mapped-globals/-m option is deprecated (a mapped "
             "globals file is no longer needed as we use wasm globals)"
          << std::endl;
      })
    .add("--mem-init",
         "-t",
         "Import a memory initialization file into the output module",
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["mem init"] = argument;
         })
    .add("--mem-base",
         "-mb",
         "Set the location to write the memory initialization (--mem-init) "
         "file (GLOBAL_BASE in emscripten). If not provided, the __memory_base "
         "global import is used.",
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["mem base"] = argument;
         })
    .add("--mem-max",
         "-mm",
         "Set the maximum size of memory in the wasm module (in bytes). -1 "
         "means no limit. Without this, TOTAL_MEMORY is used (as it is used "
         "for the initial value), or if memory growth is enabled, no limit is "
         "set. This overrides both of those.",
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["mem max"] = argument;
         })
    .add("--total-memory",
         "-m",
         "Total memory size",
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["total memory"] = argument;
         })
    .add("--table-max",
         "-tM",
         "Set the maximum size of the table. Without this, it is set depending "
         "on how many functions are in the module. -1 means no limit",
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["table max"] = argument;
         })
    .add("--no-opts",
         "-n",
         "Disable optimization passes (deprecated)",
         Options::Arguments::Zero,
         [](Options* o, const std::string&) {
           std::cerr << "--no-opts is deprecated (use -O0, etc.)\n";
         })
    .add("--trap-mode",
         "",
         "Strategy for handling potentially trapping instructions. Valid "
         "values are \"allow\", \"js\", and \"clamp\"",
         Options::Arguments::One,
         [&trapMode](Options* o, const std::string& argument) {
           try {
             trapMode = trapModeFromString(argument);
           } catch (std::invalid_argument& e) {
             std::cerr << "Error: " << e.what() << "\n";
             exit(EXIT_FAILURE);
           }
         })
    .add("--wasm-only",
         "-w",
         "Input is in WebAssembly-only format, and not actually valid asm.js",
         Options::Arguments::Zero,
         [&wasmOnly](Options* o, const std::string&) { wasmOnly = true; })
    .add("--no-legalize-javascript-ffi",
         "-nj",
         "Do not fully legalize (i64->i32, f32->f64) the imports and exports "
         "for interfacing with JS",
         Options::Arguments::Zero,
         [&legalizeJavaScriptFFI](Options* o, const std::string&) {
           legalizeJavaScriptFFI = false;
         })
    .add("--source-map",
         "-sm",
         "Emit source map (if using binary output) to the specified file",
         Options::Arguments::One,
         [&sourceMapFilename](Options* o, const std::string& argument) {
           sourceMapFilename = argument;
         })
    .add("--source-map-url",
         "-su",
         "Use specified string as source map URL",
         Options::Arguments::One,
         [&sourceMapUrl](Options* o, const std::string& argument) {
           sourceMapUrl = argument;
         })
    .add("--symbolmap",
         "-s",
         "Emit a symbol map (indexes => names)",
         Options::Arguments::One,
         [&](Options* o, const std::string& argument) { symbolMap = argument; })
    .add("--emit-text",
         "-S",
         "Emit text instead of binary for the output file",
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) { emitBinary = false; })
    .add_positional("INFILE",
                    Options::Arguments::One,
                    [](Options* o, const std::string& argument) {
                      o->extra["infile"] = argument;
                    });
  options.parse(argc, argv);

  // finalize arguments
  if (options.extra["output"].size() == 0) {
    // when no output file is specified, we emit text to stdout
    emitBinary = false;
  }

  if (options.runningDefaultOptimizationPasses()) {
    if (options.passes.size() > 1) {
      Fatal() << "asm2wasm can only run default optimization passes (-O, -Ox, "
                 "etc.), and not specific additional passes";
    }
  }

  const auto& tm_it = options.extra.find("total memory");
  size_t totalMemory = tm_it == options.extra.end()
                         ? 16 * 1024 * 1024
                         : atoll(tm_it->second.c_str());
  if (totalMemory & ~Memory::kPageMask) {
    std::cerr << "Error: total memory size " << totalMemory
              << " is not a multiple of the 64k wasm page size\n";
    exit(EXIT_FAILURE);
  }

  Asm2WasmPreProcessor pre;
  // wasm binaries can contain a names section, but not full debug info --
  // debug info is disabled if a map file is not specified with wasm binary
  pre.debugInfo =
    options.passOptions.debugInfo && (!emitBinary || sourceMapFilename.size());
  auto input(read_file<std::vector<char>>(options.extra["infile"],
                                          Flags::Text,
                                          options.debug ? Flags::Debug
                                                        : Flags::Release));
  char* start = pre.process(input.data());

  if (options.debug) {
    std::cerr << "parsing..." << std::endl;
  }
  cashew::Parser<Ref, DotZeroValueBuilder> builder;
  Ref asmjs = builder.parseToplevel(start);

  if (options.debug) {
    std::cerr << "wasming..." << std::endl;
  }
  Module wasm;

  // set up memory
  wasm.memory.initial = wasm.memory.max = totalMemory / Memory::kPageSize;

  // import mem init file, if provided (do this before compiling the module,
  // since the optimizer should see the memory segments)
  const auto& memInit = options.extra.find("mem init");
  if (memInit != options.extra.end()) {
    auto filename = memInit->second.c_str();
    auto data(read_file<std::vector<char>>(
      filename, Flags::Binary, options.debug ? Flags::Debug : Flags::Release));
    // create the memory segment
    Expression* init;
    const auto& memBase = options.extra.find("mem base");
    if (memBase == options.extra.end()) {
      init = Builder(wasm).makeGlobalGet(MEMORY_BASE, i32);
    } else {
      init = Builder(wasm).makeConst(
        Literal(int32_t(atoi(memBase->second.c_str()))));
    }
    wasm.memory.segments.emplace_back(init, data);
  }

  // set up the module's features, needed by optimization and validation passes
  options.applyFeatures(wasm);

  // compile the code
  Asm2WasmBuilder asm2wasm(wasm,
                           pre,
                           options.debug,
                           trapMode,
                           options.passOptions,
                           legalizeJavaScriptFFI,
                           options.runningDefaultOptimizationPasses(),
                           wasmOnly);
  asm2wasm.processAsm(asmjs);

  // finalize the imported mem init
  if (memInit != options.extra.end()) {
    if (options.runningDefaultOptimizationPasses()) {
      PassRunner runner(&wasm);
      runner.add("memory-packing");
      runner.run();
    }
  }

  // Set the max memory size, if requested
  const auto& memMax = options.extra.find("mem max");
  if (memMax != options.extra.end()) {
    uint64_t max = strtoull(memMax->second.c_str(), nullptr, 10);
    if (max != uint64_t(-1)) {
      wasm.memory.max = max / Memory::kPageSize;
    } else {
      wasm.memory.max = Memory::kUnlimitedSize;
    }
  }
  // Set the table sizes, if requested
  const auto& tableMax = options.extra.find("table max");
  if (tableMax != options.extra.end()) {
    int max = atoi(tableMax->second.c_str());
    if (max >= 0) {
      wasm.table.max = max;
    } else {
      wasm.table.max = Table::kUnlimitedSize;
    }
  }

  if (options.passOptions.validate) {
    if (!WasmValidator().validate(wasm)) {
      WasmPrinter::printModule(&wasm);
      Fatal() << "error in validating output";
    }
  }

  if (options.debug) {
    std::cerr << "emitting..." << std::endl;
  }
  ModuleWriter writer;
  writer.setDebug(options.debug);
  writer.setDebugInfo(options.passOptions.debugInfo);
  writer.setSymbolMap(symbolMap);
  writer.setBinary(emitBinary);
  if (emitBinary) {
    writer.setSourceMapFilename(sourceMapFilename);
    writer.setSourceMapUrl(sourceMapUrl);
  }
  writer.write(wasm, options.extra["output"]);

  if (options.debug) {
    std::cerr << "done." << std::endl;
  }
}
