// 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_;
  int mmap_length_;
};

MappedOutputFile::MappedOutputFile(const char* name, size_t estimated_size)
    : estimated_size_(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),
                                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;
  impl_->mmap_length_ = mmap_length;
  buffer_ = reinterpret_cast<u1*>(mapped);
  opened_ = true;
}


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

int MappedOutputFile::Close(size_t size) {
  if (size > estimated_size_) {
    snprintf(errmsg, MAX_ERROR, "size %zu > estimated size %zu", size,
             estimated_size_);
    errmsg_ = errmsg;
    return -1;
  }
  munmap(buffer_, impl_->mmap_length_);
  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
