// Copyright 2015 The Bazel Authors. All rights reserved.
//
// 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>

#include <algorithm>

#include "third_party/ijar/mapped_file.h"

#define MAX_ERROR 2048

namespace devtools_ijar {

static char errmsg[MAX_ERROR];

struct MappedInputFileImpl {
  size_t discarded_;
  int fd_;
};

MappedInputFile::MappedInputFile(const char* name) {
  impl_ = NULL;
  opened_ = false;

  int fd = open(name, O_RDONLY);
  if (fd < 0) {
    snprintf(errmsg, MAX_ERROR, "open(): %s", strerror(errno));
    errmsg_ = errmsg;
    return;
  }

  off_t length = lseek(fd, 0, SEEK_END);
  if (length < 0) {
    snprintf(errmsg, MAX_ERROR, "lseek(): %s", strerror(errno));
    errmsg_ = errmsg;
    return;
  }

  void* buffer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
  if (buffer == MAP_FAILED) {
    snprintf(errmsg, MAX_ERROR, "mmap(): %s", strerror(errno));
    errmsg_ = errmsg;
    return;
  }

  impl_ = new MappedInputFileImpl();
  impl_->fd_ = fd;
  impl_->discarded_ = 0;
  buffer_ = reinterpret_cast<u1*>(buffer);
  length_ = length;
  opened_ = true;
}

MappedInputFile::~MappedInputFile() {
  delete impl_;
}

void MappedInputFile::Discard(size_t bytes) {
  munmap(buffer_ + impl_->discarded_, bytes);
  impl_->discarded_ += bytes;
}

int MappedInputFile::Close() {
  if (close(impl_->fd_) < 0) {
    snprintf(errmsg, MAX_ERROR, "close(): %s", strerror(errno));
    errmsg_ = errmsg;
    return -1;
  }

  return 0;
}

struct MappedOutputFileImpl {
  int fd_;
};

MappedOutputFile::MappedOutputFile(const char* name, u8 estimated_size) {
  impl_ = NULL;
  opened_ = false;
  int fd = open(name, O_CREAT|O_RDWR|O_TRUNC, 0644);
  if (fd < 0) {
    snprintf(errmsg, MAX_ERROR, "open(): %s", strerror(errno));
    errmsg_ = errmsg;
    return;
  }

  // Create mmap-able sparse file
  if (ftruncate(fd, estimated_size) < 0) {
    snprintf(errmsg, MAX_ERROR, "ftruncate(): %s", strerror(errno));
    errmsg_ = errmsg;
    return;
  }

  // Ensure that any buffer overflow in JarStripper will result in
  // SIGSEGV or SIGBUS by over-allocating beyond the end of the file.
  size_t mmap_length = std::min(estimated_size + sysconf(_SC_PAGESIZE),
                                (u8) std::numeric_limits<size_t>::max());
  void* mapped = mmap(NULL, mmap_length, PROT_WRITE, MAP_SHARED, fd, 0);
  if (mapped == MAP_FAILED) {
    snprintf(errmsg, MAX_ERROR, "mmap(): %s", strerror(errno));
    errmsg_ = errmsg;
    return;
  }

  impl_ = new MappedOutputFileImpl();
  impl_->fd_ = fd;
  buffer_ = reinterpret_cast<u1*>(mapped);
  opened_ = true;
}


MappedOutputFile::~MappedOutputFile() {
  delete impl_;
}

int MappedOutputFile::Close(int size) {
  if (ftruncate(impl_->fd_, size) < 0) {
    snprintf(errmsg, MAX_ERROR, "ftruncate(): %s", strerror(errno));
    errmsg_ = errmsg;
    return -1;
  }

  if (close(impl_->fd_) < 0) {
    snprintf(errmsg, MAX_ERROR, "close(): %s", strerror(errno));
    errmsg_ = errmsg;
    return -1;
  }

  return 0;
}

}  // namespace devtools_ijar
