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

#include "support/file.h"
#include "support/debug.h"
#include "support/path.h"
#include "support/utilities.h"

#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <limits>

#define DEBUG_TYPE "file"

std::vector<char> wasm::read_stdin() {
  BYN_TRACE("Loading stdin...\n");
  std::vector<char> input;
  char c;
  while (std::cin.get(c) && !std::cin.eof()) {
    input.push_back(c);
  }
  return input;
}

template<typename T> struct do_read_stdin {
  T operator()();
};

template<> std::vector<char> do_read_stdin<std::vector<char>>::operator()() {
  return wasm::read_stdin();
}

template<> std::string do_read_stdin<std::string>::operator()() {
  auto vec = wasm::read_stdin();
  return std::string(vec.begin(), vec.end());
}

template<typename T>
T wasm::read_file(const std::string& filename, Flags::BinaryOption binary) {
  if (filename == "-") {
    return do_read_stdin<T>{}();
  }
  BYN_TRACE("Loading '" << filename << "'...\n");
  std::ifstream infile;
  std::ios_base::openmode flags = std::ifstream::in;
  if (binary == Flags::Binary) {
    flags |= std::ifstream::binary;
  }
  infile.open(wasm::Path::to_path(filename), flags);
  if (!infile.is_open()) {
    Fatal() << "Failed opening '" << filename << "'";
  }
  infile.seekg(0, std::ios::end);
  std::streampos insize = infile.tellg();
  if (uint64_t(insize) >= std::numeric_limits<size_t>::max()) {
    // Building a 32-bit executable where size_t == 32 bits, we are not able to
    // create strings larger than 2^32 bytes in length, so must abort here.
    Fatal() << "Failed opening '" << filename
            << "': Input file too large: " << insize
            << " bytes. Try rebuilding in 64-bit mode.";
  }
  // Zero-initialize the string or vector with the expected size.
  T input(size_t(insize), '\0');
  if (size_t(insize) == 0) {
    return input;
  }
  infile.seekg(0);
  infile.read(&input[0], insize);
  if (binary == Flags::Text) {
    size_t chars = size_t(infile.gcount());
    // Truncate size to the number of ASCII characters actually read in text
    // mode (which is generally less than the number of bytes on Windows, if
    // \r\n line endings are present)
    input.resize(chars);
  }
  return input;
}

std::string wasm::read_possible_response_file(const std::string& input) {
  if (input.size() == 0 || input[0] != '@') {
    return input;
  }
  return wasm::read_file<std::string>(input.substr(1), Flags::Text);
}

// Explicit instantiations for the explicit specializations.
template std::string wasm::read_file<>(const std::string&, Flags::BinaryOption);
template std::vector<char> wasm::read_file<>(const std::string&,
                                             Flags::BinaryOption);

wasm::Output::Output(const std::string& filename, Flags::BinaryOption binary)
  : outfile(), out([this, filename, binary]() {
      // Ensure a single return at the very end, to avoid clang-tidy warnings
      // about the types of different returns here.
      std::streambuf* buffer;
      if (filename == "-" || filename.empty()) {
        buffer = std::cout.rdbuf();
      } else {
        BYN_TRACE("Opening '" << filename << "'\n");
        std::ios_base::openmode flags =
          std::ofstream::out | std::ofstream::trunc;
        if (binary == Flags::Binary) {
          flags |= std::ofstream::binary;
        }
        outfile.open(wasm::Path::to_path(filename), flags);
        if (!outfile.is_open()) {
          Fatal() << "Failed opening output file '" << filename
                  << "': " << strerror(errno);
        }
        buffer = outfile.rdbuf();
      }
      return buffer;
    }()) {}

void wasm::copy_file(std::string input, std::string output) {
  std::ifstream src(wasm::Path::to_path(input), std::ios::binary);
  std::ofstream dst(wasm::Path::to_path(output), std::ios::binary);
  dst << src.rdbuf();
}

size_t wasm::file_size(std::string filename) {
  std::ifstream infile(wasm::Path::to_path(filename),
                       std::ifstream::ate | std::ifstream::binary);
  return infile.tellg();
}

void wasm::flush_and_quick_exit(int code) {
  // We expect C++ files to be flushed by their destructors already. Flush the
  // standard streams manually.
  std::cout << std::flush;
  std::cerr << std::flush;

  // To be safe, also flush at the C level.
  fflush(NULL);

#if __has_feature(address_sanitizer) || __has_feature(thread_sanitizer) ||     \
  __has_feature(memory_sanitizer) || __has_feature(leak_sanitizer) ||          \
  __has_feature(undefined_behavior_sanitizer)
  // Avoid quick_exit when using sanitizers, so that leak checks and other
  // things can run during shutdown normally.
  std::exit(code);
#else
  // A "better" function to use here would be std::quick_exit, however on older
  // version of macOS (at least as new as 13.2 which currently runs on our CI)
  // the C symbol _quick_exit (which is called by std::quick_exit) is missing.
  // So instead use _Exit(); the only difference is that _Exit() does not call
  // handlers registered by at_quick_exit(). Currently Binaryen does not have
  // any of those.
  _Exit(code);
#endif
}
