/*
 * Copyright 2012, 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.
 */

#include "bcc/Support/FileBase.h"

#include "bcc/Support/Log.h"

#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>

#include <cerrno>
#include <cstring>
#include <new>

#include <utils/FileMap.h>

using namespace bcc;

#ifdef _WIN32
// TODO: Fix flock usage under windows
#define LOCK_SH 0
#define LOCK_EX 0
#define LOCK_NB 0
#define LOCK_UN 0

int flock(int fd, int operation) {
  return 0;
}
#endif  // _WIN32

FileBase::FileBase(const std::string &pFilename,
                   unsigned pOpenFlags,
                   unsigned pFlags)
  : mFD(-1),
    mError(),
    mName(pFilename), mOpenFlags(pOpenFlags),
    mShouldUnlock(false),
    mShouldDelete(false) {
  // Process pFlags
#ifdef O_BINARY
  if (pFlags & kBinary) {
    mOpenFlags |= O_BINARY;
  }
#endif
  if (pFlags & kTruncate) {
    mOpenFlags |= O_TRUNC;
  }

  if (pFlags & kAppend) {
    mOpenFlags |= O_APPEND;
  }

  if (pFlags & kDeleteOnClose) {
    mShouldDelete = true;
  }

  // Open the file.
  open();

  return;
}

FileBase::~FileBase() {
  close();
}

bool FileBase::open() {
  do {
    // FIXME: Hard-coded permissions (0644) for newly created file should be
    //        removed and provide a way to let the user configure the value.
    mFD = ::open(mName.c_str(), mOpenFlags, 0644);
    if (mFD > 0) {
      return true;
    }

    // Some errors occurred ...
    if (errno != EINTR) {
      detectError();
      return false;
    }
  } while (true);
  // unreachable
}


bool FileBase::checkFileIntegrity() {
  // Check the file integrity by examining whether the inode referring to the mFD
  // and to the file mName are the same.
  struct stat fd_stat, file_stat;

  // Get the file status of file descriptor mFD.
  do {
    if (::fstat(mFD, &fd_stat) == 0) {
      break;
    } else if (errno != EINTR) {
      detectError();
      return false;
    }
  } while (true);

  // Get the file status of file mName.
  do {
    if (::stat(mName.c_str(), &file_stat) == 0) {
      break;
    } else if (errno != EINTR) {
      detectError();
      return false;
    }
  } while (true);

  return ((fd_stat.st_dev == file_stat.st_dev) &&
          (fd_stat.st_ino == file_stat.st_ino));
}

void FileBase::detectError() {
  // Read error from errno.
  mError.assign(errno, std::generic_category());
}

bool FileBase::lock(enum LockModeEnum pMode,
                    bool pNonblocking,
                    unsigned pMaxRetry,
                    useconds_t pRetryInterval) {
  int lock_operation;
  unsigned retry = 0;

  // Check the state.
  if ((mFD < 0) || hasError()) {
    return false;
  }

  // Return immediately if it's already locked.
  if (mShouldUnlock) {
    return true;
  }

  // Determine the lock operation (2nd argument) to the flock().
  if (pMode == kReadLock) {
    lock_operation = LOCK_SH;
  } else if (pMode == kWriteLock) {
    lock_operation = LOCK_EX;
  } else {
    mError = std::make_error_code(std::errc::invalid_argument);
    return false;
  }

  if (pNonblocking) {
    lock_operation |= LOCK_NB;
  }

  do {
    if (::flock(mFD, lock_operation) == 0) {
      mShouldUnlock = true;
      // Here we got a lock but we need to check whether the mFD still
      // "represents" the filename (mName) we opened in the contructor. This
      // check may failed when another process deleted the original file mFD
      // mapped when we were trying to obtain the lock on the file.
      if (!checkFileIntegrity()) {
        if (hasError() || !reopen()) {
          // Error occurred when check the file integrity or re-open the file.
          return false;
        } else {
          // Wait a while before the next try.
          ::usleep(pRetryInterval);
          retry++;
          continue;
        }
      }

      return true;
    }

    // flock() was not performed successfully. Check the errno to see whether
    // it's retry-able.
    if (errno == EINTR) {
      // flock() was interrupted by delivery of a signal. Restart without
      // decrement the retry counter.
      continue;
    } else if (errno == EWOULDBLOCK) {
      // The file descriptor was locked by others, wait for a while before next
      // retry.
      retry++;
      ::usleep(pRetryInterval);
    } else {
      // There's a fatal error occurs when perform flock(). Return immediately
      // without further retry.
      detectError();
      return false;
    }
  } while (retry <= pMaxRetry);

  return false;
}

void FileBase::unlock() {
  if (mFD < 0) {
    return;
  }

  do {
    if (::flock(mFD, LOCK_UN) == 0) {
      mShouldUnlock = false;
      return;
    }
  } while (errno == EINTR);

  detectError();
  return;
}

android::FileMap *FileBase::createMap(off_t pOffset, size_t pLength,
                                      bool pIsReadOnly) {
  if (mFD < 0 || hasError()) {
    return nullptr;
  }

  android::FileMap *map = new (std::nothrow) android::FileMap();
  if (map == nullptr) {
    mError = make_error_code(std::errc::not_enough_memory);
    return nullptr;
  }

  if (!map->create(nullptr, mFD, pOffset, pLength, pIsReadOnly)) {
    detectError();
    delete map;
    return nullptr;
  }

  return map;
}

size_t FileBase::getSize() {
  if (mFD < 0 || hasError()) {
    return static_cast<size_t>(-1);
  }

  struct stat file_stat;
  do {
    if (::fstat(mFD, &file_stat) == 0) {
      break;
    } else if (errno != EINTR) {
      detectError();
      return static_cast<size_t>(-1);
    }
  } while (true);

  return file_stat.st_size;
}

off_t FileBase::seek(off_t pOffset) {
  if ((mFD < 0) || hasError()) {
    return static_cast<off_t>(-1);
  }

  do {
    off_t result = ::lseek(mFD, pOffset, SEEK_SET);
    if (result == pOffset) {
      return result;
    }
  } while (errno == EINTR);

  detectError();
  return static_cast<off_t>(-1);
}

off_t FileBase::tell() {
  if ((mFD < 0) || hasError()) {
    return static_cast<off_t>(-1);
  }

  do {
    off_t result = ::lseek(mFD, 0, SEEK_CUR);
    if (result != static_cast<off_t>(-1)) {
      return result;
    }
  } while (errno == EINTR);

  detectError();
  return static_cast<off_t>(-1);
}

void FileBase::close() {
  if (mShouldUnlock) {
    unlock();
    mShouldUnlock = false;
  }
  if (mFD > 0) {
    ::close(mFD);
    mFD = -1;
  }
  if (mShouldDelete) {
    int res = ::remove(mName.c_str());
    if (res != 0) {
      ALOGE("Failed to remove file: %s - %s", mName.c_str(), ::strerror(res));
    }
  }
  return;
}
