// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "file_reader.h"

#include <errno.h>
#include <fcntl.h>
#include <lib/syslog/cpp/macros.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

#include <cstdint>
#include <memory>
#include <vector>

#include "src/lib/files/file.h"

namespace perfmon {

bool FileReader::Create(FileNameProducer file_name_producer, uint32_t num_traces,
                        std::unique_ptr<FileReader>* out_reader) {
  out_reader->reset(new FileReader(std::move(file_name_producer), num_traces));
  return true;
}

FileReader::FileReader(FileNameProducer file_name_producer, uint32_t num_traces)
    : Reader(num_traces), file_name_producer_(std::move(file_name_producer)) {}

bool FileReader::MapBuffer(const std::string& name, uint32_t trace_num) {
  if (!UnmapBuffer()) {
    return false;
  }

  std::string file_name = file_name_producer_(trace_num);
  int raw_fd = open(file_name.c_str(), O_RDONLY);
  if (raw_fd < 0) {
    FX_LOGS(ERROR) << name << ": Unable to open buffer file: " << file_name << ": "
                   << strerror(errno);
    return false;
  }
  fbl::unique_fd fd(raw_fd);
  file_size_ = lseek(raw_fd, 0, SEEK_END);
  lseek(raw_fd, 0, SEEK_SET);
#ifdef __Fuchsia__
  // Mmap can currently fail if the file is on minfs, so just punt.
  void* mapped_buffer = reinterpret_cast<void*>(-1);
#else
  void* mapped_buffer = mmap(nullptr, file_size_, PROT_READ, MAP_PRIVATE, raw_fd, 0);
  if (mapped_buffer == reinterpret_cast<void*>(-1)) {
    FX_VLOGS(2) << name << ": Unable to map buffer file: " << file_name << ": " << strerror(errno);
  }
#endif
  if (mapped_buffer == reinterpret_cast<void*>(-1)) {
    std::vector<uint8_t> data;
    if (!files::ReadFileDescriptorToVector(raw_fd, &data)) {
      FX_LOGS(ERROR) << "Error reading: " << file_name;
      return false;
    }
    if (data.size() != file_size_) {
      FX_LOGS(ERROR) << "Error reading: " << file_name << ": got " << data.size()
                     << " bytes instead of expected " << file_size_;
      return false;
    }
    buffer_ = std::move(data);
    buffer_ptr_ = buffer_.data();
    file_is_mmapped_ = false;
  } else {
    buffer_ptr_ = mapped_buffer;
    file_is_mmapped_ = true;
  }

  ReaderStatus status = BufferReader::Create(name, buffer_ptr_, file_size_, &buffer_reader_);
  return status == ReaderStatus::kOk;
}

bool FileReader::UnmapBuffer() {
  if (buffer_ptr_) {
    buffer_reader_.reset();
    if (file_is_mmapped_) {
      auto buffer = const_cast<void*>(buffer_ptr_);
      int error = munmap(buffer, file_size_);
      if (error != 0) {
        FX_LOGS(ERROR) << "Unable to unmap buffer: " << strerror(errno);
        return false;
      }
    }
    buffer_ptr_ = nullptr;
    buffer_ = std::vector<uint8_t>();  // Ensure the vector's data is freed
  }
  return true;
}

}  // namespace perfmon
