/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.
 */
#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_AUTO_RESOURCES_AUTO_RESOURCES_H_
#define CUTTLEFISH_COMMON_COMMON_LIBS_AUTO_RESOURCES_AUTO_RESOURCES_H_

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>

template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];

template <typename T, size_t N>
char (&ArraySizeHelper(const T (&array)[N]))[N];

#define arraysize(array) (sizeof(ArraySizeHelper(array)))

// Automatically close a file descriptor
class AutoCloseFILE {
 public:
  explicit AutoCloseFILE(FILE *f) : f_(f) { }
  virtual ~AutoCloseFILE() {
    if (f_) {
      (void)::fclose(f_);
      f_ = NULL;
    }
  }

  operator FILE*() const {
    return f_;
  }

  bool CopyFrom(const AutoCloseFILE& in);

  bool IsError() const {
    return f_ == NULL;
  }

  bool IsEOF() const {
    return IsError() || feof(f_);
  }

  bool IsOpen() const {
    return f_ != NULL;
  }

  // Close the underlying file descriptor, returning a status to give the caller
  // the chance to act on failure to close.
  // Returns true on success.
  bool close() {
    bool rval = true;
    if (f_) {
      rval = !::fclose(f_);
      f_ = NULL;
    }
    return rval;
  }

 private:
  AutoCloseFILE& operator=(const AutoCloseFILE & o);
  explicit AutoCloseFILE(const AutoCloseFILE &);

  FILE* f_;
};

// Automatically close a file descriptor
class AutoCloseFileDescriptor {
 public:
  explicit AutoCloseFileDescriptor(int fd) : fd_(fd) { }
  virtual ~AutoCloseFileDescriptor() {
    if (fd_ != -1) {
      (void)::close(fd_);
      fd_ = -1;
    }
  }

  operator int() const {
    return fd_;
  }

  bool IsError() const {
    return fd_ == -1;
  }

  // Close the underlying file descriptor, returning a status to give the caller
  // the chance to act on failure to close.
  // Returns true on success.
  bool close() {
    bool rval = true;
    if (fd_ != -1) {
      rval = !::close(fd_);
      fd_ = -1;
    }
    return rval;
  }

 private:
  AutoCloseFileDescriptor& operator=(const AutoCloseFileDescriptor & o);
  explicit AutoCloseFileDescriptor(const AutoCloseFileDescriptor &);

  int fd_;
};

// In C++11 this is just std::vector<char>, but Android isn't
// there yet.
class AutoFreeBuffer {
 public:
  enum {
    // Minimum reserve size of AutoFreeBuffer to consider shrinking reservation.
    // Any buffer shorter than this will not be shrunk.
    kAutoBufferShrinkReserveThreshold = 8192
  };

  AutoFreeBuffer()
      : data_(NULL), size_(0), reserve_size_(0) {}

  AutoFreeBuffer(size_t reserve_size)
      : data_(NULL), size_(0), reserve_size_(0) {
    Reserve(reserve_size);
  }

  ~AutoFreeBuffer();
  void Clear();
  bool Resize(size_t newsize);
  bool Reserve(size_t newsize);
  bool SetToString(const char* in);
  bool Append(const void* new_data, size_t new_data_size);
  size_t PrintF(const char* format, ... );

  char* data() {
    return data_;
  }

  const char* data() const {
    return data_;
  }

  char* begin() {
    return data_;
  }

  const char* begin() const {
    return data_;
  }

  char* end() {
    return data_ + size_;
  }

  const char* end() const {
    return data_ + size_;
  }

  size_t size() const {
    return size_;
  }

  size_t reserve_size() const {
    return reserve_size_;
  }

  void Swap(AutoFreeBuffer& other) {
    char* temp_ptr = data_;
    data_ = other.data_;
    other.data_ = temp_ptr;

    size_t temp_size = size_;
    size_ = other.size_;
    other.size_ = temp_size;

    temp_size = reserve_size_;
    reserve_size_ = other.reserve_size_;
    other.reserve_size_ = temp_size;
  }

  bool operator==(const AutoFreeBuffer& other) const {
    return (size_ == other.size_) && !memcmp(data_, other.data_, size_);
  }

  bool operator!=(const AutoFreeBuffer& other) const {
    return !(*this == other);
  }

 protected:
  char *data_;
  size_t size_;
  size_t reserve_size_;

 private:
  AutoFreeBuffer& operator=(const AutoFreeBuffer&);
  explicit AutoFreeBuffer(const AutoFreeBuffer&);
};

class AutoUMask {
 public:
  explicit AutoUMask(mode_t mask) {
      prev_umask = umask(mask);
  }

  ~AutoUMask() {
    umask(prev_umask);
  }
 private:
  mode_t prev_umask;
};
#endif  // CUTTLEFISH_COMMON_COMMON_LIBS_AUTO_RESOURCES_AUTO_RESOURCES_H_
