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

//
// Abstracts reading and writing, supporting both text and binary.
//

#ifndef wasm_wasm_io_h
#define wasm_wasm_io_h

#include "pass.h"
#include "support/file.h"
#include "wasm.h"

namespace wasm {

class ModuleIOBase {
protected:
  bool debugInfo;

public:
  // Whether we support debug info (the names section).
  void setDebugInfo(bool debugInfo_) { debugInfo = debugInfo_; }
};

class ModuleReader : public ModuleIOBase {
public:
  // Reading defaults to loading the names section. Name section info is used in
  // various internal ways that we do not opt-in to currently.
  ModuleReader() { setDebugInfo(true); }

  // If DWARF support is enabled, we track the locations of all IR nodes in
  // the binary, so that we can update DWARF sections later when writing.
  void setDWARF(bool DWARF_) { DWARF = DWARF_; }

  void setProfile(IRProfile profile_) { profile = profile_; }

  // TODO: add support for this in the text format as well
  void setSkipFunctionBodies(bool skipFunctionBodies_) {
    skipFunctionBodies = skipFunctionBodies_;
  }

  // read text
  void readText(std::string filename, Module& wasm);
  // read binary
  void readBinary(std::string filename,
                  Module& wasm,
                  std::string sourceMapFilename = "");
  // read text or binary, checking the contents for what it is. If `filename` is
  // empty, read from stdin.
  void
  read(std::string filename, Module& wasm, std::string sourceMapFilename = "");
  // check whether a file is a wasm binary
  bool isBinaryFile(std::string filename);

  FeatureSet getFeaturesSectionFeatures() { return featuresSectionFeatures; }

private:
  bool DWARF = false;

  IRProfile profile = IRProfile::Normal;

  bool skipFunctionBodies = false;

  FeatureSet featuresSectionFeatures = FeatureSet::MVP;

  void readStdin(Module& wasm, std::string sourceMapFilename);

  void readBinaryData(std::vector<char>& input,
                      Module& wasm,
                      std::string sourceMapFilename);
};

class ModuleWriter : public ModuleIOBase {
  const PassOptions& options;

  bool binary = true;

  // TODO: Remove `emitModuleName`. See the comment in wasm-binary.h
  bool emitModuleName = false;

  std::string symbolMap;
  std::string sourceMapFilename;
  std::string sourceMapUrl;

public:
  // Writing defaults to not storing the names section. Storing it is a user-
  // observable fact that must be opted into.
  ModuleWriter(const PassOptions& options) : options(options) {
    setDebugInfo(false);
  }

  void setBinary(bool binary_) { binary = binary_; }
  void setSymbolMap(std::string symbolMap_) { symbolMap = symbolMap_; }
  void setSourceMapFilename(std::string sourceMapFilename_) {
    sourceMapFilename = sourceMapFilename_;
  }
  void setSourceMapUrl(std::string sourceMapUrl_) {
    sourceMapUrl = sourceMapUrl_;
  }
  void setEmitModuleName(bool set) { emitModuleName = set; }

  // write text
  void writeText(Module& wasm, Output& output);
  void writeText(Module& wasm, std::string filename);
  // write binary
  void writeBinary(Module& wasm, Output& output);
  void writeBinary(Module& wasm, std::string filename);
  // write text or binary, defaulting to binary unless setBinary(false),
  // and unless there is no output file (in which case we write text
  // to stdout).
  void write(Module& wasm, Output& output);
  void write(Module& wasm, std::string filename);
};

} // namespace wasm

#endif // wasm_wasm_io_h
