// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__

#include <errno.h>

#include <algorithm>
#include <set>
#include <string>
#include <vector>

#include <glib.h>

#include "update_engine/action.h"
#include "update_engine/action_processor.h"

namespace chromeos_update_engine {

namespace utils {

// Returns true if this is an official Chrome OS build, false otherwise.
bool IsOfficialBuild();

// Returns true if the OOBE process has been completed and EULA accepted, false
// otherwise.
bool IsOOBEComplete();

// Writes the data passed to path. The file at path will be overwritten if it
// exists. Returns true on success, false otherwise.
bool WriteFile(const char* path, const char* data, int data_len);

// Calls write() or pwrite() repeatedly until all count bytes at buf are
// written to fd or an error occurs. Returns true on success.
bool WriteAll(int fd, const void* buf, size_t count);
bool PWriteAll(int fd, const void* buf, size_t count, off_t offset);

// Calls pread() repeatedly until count bytes are read, or EOF is reached.
// Returns number of bytes read in *bytes_read. Returns true on success.
bool PReadAll(int fd, void* buf, size_t count, off_t offset,
              ssize_t* out_bytes_read);

// Returns the entire contents of the file at path. Returns true on success.
bool ReadFile(const std::string& path, std::vector<char>* out);
bool ReadFileToString(const std::string& path, std::string* out);

// Returns the size of the file at path. If the file doesn't exist or some
// error occurrs, -1 is returned.
off_t FileSize(const std::string& path);

std::string ErrnoNumberAsString(int err);

// Strips duplicate slashes, and optionally removes all trailing slashes.
// Does not compact /./ or /../.
std::string NormalizePath(const std::string& path, bool strip_trailing_slash);

// Returns true if the file exists for sure. Returns false if it doesn't exist,
// or an error occurs.
bool FileExists(const char* path);

// Returns true if |path| exists and is a symbolic link.
bool IsSymlink(const char* path);

// The last 6 chars of path must be XXXXXX. They will be randomly changed
// and a non-existent path will be returned. Intentionally makes a copy
// of the string passed in.
// NEVER CALL THIS FUNCTION UNLESS YOU ARE SURE
// THAT YOUR PROCESS WILL BE THE ONLY THING WRITING FILES IN THIS DIRECTORY.
std::string TempFilename(std::string path);

// Calls mkstemp() with the template passed. Returns the filename in the
// out param filename. If fd is non-NULL, the file fd returned by mkstemp
// is not close()d and is returned in the out param 'fd'. However, if
// fd is NULL, the fd from mkstemp() will be closed.
// The last six chars of the template must be XXXXXX.
// Returns true on success.
bool MakeTempFile(const std::string& filename_template,
                  std::string* filename,
                  int* fd);

// Calls mkdtemp() with the tempate passed. Returns the generated dirname
// in the dirname param. Returns TRUE on success. dirname must not be NULL.
bool MakeTempDirectory(const std::string& dirname_template,
                       std::string* dirname);

// Deletes a directory and all its contents synchronously. Returns true
// on success. This may be called with a regular file--it will just unlink it.
// This WILL cross filesystem boundaries.
bool RecursiveUnlinkDir(const std::string& path);

// Returns the root device for a partition. For example,
// RootDevice("/dev/sda3") returns "/dev/sda". Returns an empty string
// if the input device is not of the "/dev/xyz" form.
std::string RootDevice(const std::string& partition_device);

// Returns the partition number, as a string, of partition_device. For example,
// PartitionNumber("/dev/sda3") returns "3".
std::string PartitionNumber(const std::string& partition_device);

// Returns the sysfs block device for a root block device. For
// example, SysfsBlockDevice("/dev/sda") returns
// "/sys/block/sda". Returns an empty string if the input device is
// not of the "/dev/xyz" form.
std::string SysfsBlockDevice(const std::string& device);

// Returns true if the root |device| (e.g., "/dev/sdb") is known to be
// removable, false otherwise.
bool IsRemovableDevice(const std::string& device);

// Synchronously mount or unmount a filesystem. Return true on success.
// Mounts as ext3 with default options.
bool MountFilesystem(const std::string& device, const std::string& mountpoint,
                     unsigned long flags);
bool UnmountFilesystem(const std::string& mountpoint);

// Returns the block count and the block byte size of the ext3 file system on
// |device| (which may be a real device or a path to a filesystem image) or on
// an opened file descriptor |fd|. The actual file-system size is |block_count|
// * |block_size| bytes. Returns true on success, false otherwise.
bool GetFilesystemSize(const std::string& device,
                       int* out_block_count,
                       int* out_block_size);
bool GetFilesystemSizeFromFD(int fd,
                             int* out_block_count,
                             int* out_block_size);

enum BootLoader {
  BootLoader_SYSLINUX = 0,
  BootLoader_CHROME_FIRMWARE = 1
};
// Detects which bootloader this system uses and returns it via the out
// param. Returns true on success.
bool GetBootloader(BootLoader* out_bootloader);

// Returns the error message, if any, from a GError pointer.
const char* GetGErrorMessage(const GError* error);

// Initiates a system reboot. Returns true on success, false otherwise.
bool Reboot();

// Fuzzes an integer |value| randomly in the range:
// [value - range / 2, value + range - range / 2]
int FuzzInt(int value, unsigned int range);

// Log a string in hex to LOG(INFO). Useful for debugging.
void HexDumpArray(const unsigned char* const arr, const size_t length);
inline void HexDumpString(const std::string& str) {
  HexDumpArray(reinterpret_cast<const unsigned char*>(str.data()), str.size());
}
inline void HexDumpVector(const std::vector<char>& vect) {
  HexDumpArray(reinterpret_cast<const unsigned char*>(&vect[0]), vect.size());
}

extern const char* const kStatefulPartition;

bool StringHasSuffix(const std::string& str, const std::string& suffix);
bool StringHasPrefix(const std::string& str, const std::string& prefix);

template<typename KeyType, typename ValueType>
bool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) {
  return m.find(k) != m.end();
}
template<typename KeyType>
bool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) {
  return s.find(k) != s.end();
}

template<typename ValueType>
std::set<ValueType> SetWithValue(const ValueType& value) {
  std::set<ValueType> ret;
  ret.insert(value);
  return ret;
}

template<typename T>
bool VectorContainsValue(const std::vector<T>& vect, const T& value) {
  return std::find(vect.begin(), vect.end(), value) != vect.end();
}

template<typename T>
bool VectorIndexOf(const std::vector<T>& vect, const T& value,
                   typename std::vector<T>::size_type* out_index) {
  typename std::vector<T>::const_iterator it = std::find(vect.begin(),
                                                         vect.end(),
                                                         value);
  if (it == vect.end()) {
    return false;
  } else {
    *out_index = it - vect.begin();
    return true;
  }
}

template<typename ValueType>
void ApplyMap(std::vector<ValueType>* collection,
              const std::map<ValueType, ValueType>& the_map) {
  for (typename std::vector<ValueType>::iterator it = collection->begin();
       it != collection->end(); ++it) {
    typename std::map<ValueType, ValueType>::const_iterator map_it =
      the_map.find(*it);
    if (map_it != the_map.end()) {
      *it = map_it->second;
    }
  }
}

// Returns the currently booted device. "/dev/sda3", for example.
// This will not interpret LABEL= or UUID=. You'll need to use findfs
// or something with equivalent funcionality to interpret those.
const std::string BootDevice();

// Returns the currently booted kernel device, "dev/sda2", for example.
// Client must pass in the boot device. The suggested calling convention
// is: BootKernelDevice(BootDevice()).
// This function works by doing string modification on boot_device.
// Returns empty string on failure.
const std::string BootKernelDevice(const std::string& boot_device);

enum ProcessPriority {
  kProcessPriorityHigh = -10,
  kProcessPriorityNormal = 0,
  kProcessPriorityLow = 10,
};

// Compares process priorities and returns an integer that is less
// than, equal to or greater than 0 if |priority_lhs| is,
// respectively, lower than, same as or higher than |priority_rhs|.
int ComparePriorities(ProcessPriority priority_lhs,
                      ProcessPriority priority_rhs);

// Sets the current process priority to |priority|. Returns true on
// success, false otherwise.
bool SetProcessPriority(ProcessPriority priority);

}  // namespace utils

// Class to unmount FS when object goes out of scope
class ScopedFilesystemUnmounter {
 public:
  explicit ScopedFilesystemUnmounter(const std::string& mountpoint)
      : mountpoint_(mountpoint),
        should_unmount_(true) {}
  ~ScopedFilesystemUnmounter() {
    if (should_unmount_) {
      utils::UnmountFilesystem(mountpoint_);
    }
  }
  void set_should_unmount(bool unmount) { should_unmount_ = unmount; }
 private:
  const std::string mountpoint_;
  bool should_unmount_;
  DISALLOW_COPY_AND_ASSIGN(ScopedFilesystemUnmounter);
};

// Utility class to close a file descriptor
class ScopedFdCloser {
 public:
  explicit ScopedFdCloser(int* fd) : fd_(fd), should_close_(true) {}
  ~ScopedFdCloser() {
    if (should_close_ && fd_ && (*fd_ >= 0)) {
      close(*fd_);
      *fd_ = -1;
    }
  }
  void set_should_close(bool should_close) { should_close_ = should_close; }
 private:
  int* fd_;
  bool should_close_;
  DISALLOW_COPY_AND_ASSIGN(ScopedFdCloser);
};

// Utility class to delete a file when it goes out of scope.
class ScopedPathUnlinker {
 public:
  explicit ScopedPathUnlinker(const std::string& path) : path_(path) {}
  ~ScopedPathUnlinker() {
    if (unlink(path_.c_str()) < 0) {
      std::string err_message = strerror(errno);
      LOG(ERROR) << "Unable to unlink path " << path_ << ": " << err_message;
    }
  }
 private:
  const std::string path_;
  DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker);
};

// Utility class to delete an empty directory when it goes out of scope.
class ScopedDirRemover {
 public:
  explicit ScopedDirRemover(const std::string& path)
      : path_(path),
        should_remove_(true) {}
  ~ScopedDirRemover() {
    if (should_remove_ && (rmdir(path_.c_str()) < 0)) {
      PLOG(ERROR) << "Unable to remove dir " << path_;
    }
  }
  void set_should_remove(bool should_remove) { should_remove_ = should_remove; }

 protected:
  const std::string path_;

 private:
  bool should_remove_;
  DISALLOW_COPY_AND_ASSIGN(ScopedDirRemover);
};

// Utility class to unmount a filesystem mounted on a temporary directory and
// delete the temporary directory when it goes out of scope.
class ScopedTempUnmounter : public ScopedDirRemover {
 public:
  explicit ScopedTempUnmounter(const std::string& path) :
      ScopedDirRemover(path) {}
  ~ScopedTempUnmounter() {
    utils::UnmountFilesystem(path_);
  }
 private:
  DISALLOW_COPY_AND_ASSIGN(ScopedTempUnmounter);
};

// A little object to call ActionComplete on the ActionProcessor when
// it's destructed.
class ScopedActionCompleter {
 public:
  explicit ScopedActionCompleter(ActionProcessor* processor,
                                 AbstractAction* action)
      : processor_(processor),
        action_(action),
        code_(kActionCodeError),
        should_complete_(true) {}
  ~ScopedActionCompleter() {
    if (should_complete_)
      processor_->ActionComplete(action_, code_);
  }
  void set_code(ActionExitCode code) { code_ = code; }
  void set_should_complete(bool should_complete) {
    should_complete_ = should_complete;
  }

 private:
  ActionProcessor* processor_;
  AbstractAction* action_;
  ActionExitCode code_;
  bool should_complete_;
  DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
};

}  // namespace chromeos_update_engine

#define TEST_AND_RETURN_FALSE_ERRNO(_x)                                        \
  do {                                                                         \
    bool _success = (_x);                                                      \
    if (!_success) {                                                           \
      std::string _msg =                                                       \
          chromeos_update_engine::utils::ErrnoNumberAsString(errno);           \
      LOG(ERROR) << #_x " failed: " << _msg;                                   \
      return false;                                                            \
    }                                                                          \
  } while (0)

#define TEST_AND_RETURN_FALSE(_x)                                              \
  do {                                                                         \
    bool _success = (_x);                                                      \
    if (!_success) {                                                           \
      LOG(ERROR) << #_x " failed.";                                            \
      return false;                                                            \
    }                                                                          \
  } while (0)

#define TEST_AND_RETURN_ERRNO(_x)                                              \
  do {                                                                         \
    bool _success = (_x);                                                      \
    if (!_success) {                                                           \
      std::string _msg =                                                       \
          chromeos_update_engine::utils::ErrnoNumberAsString(errno);           \
      LOG(ERROR) << #_x " failed: " << _msg;                                   \
      return;                                                                  \
    }                                                                          \
  } while (0)

#define TEST_AND_RETURN(_x)                                                    \
  do {                                                                         \
    bool _success = (_x);                                                      \
    if (!_success) {                                                           \
      LOG(ERROR) << #_x " failed.";                                            \
      return;                                                                  \
    }                                                                          \
  } while (0)



#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__
