//
// Copyright (C) 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.
//

#ifndef UPDATE_ENGINE_COMMON_UTILS_H_
#define UPDATE_ENGINE_COMMON_UTILS_H_

#include <errno.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <algorithm>
#include <limits>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
#include <brillo/key_value_store.h>
#include <brillo/secure_blob.h>

#include "android-base/mapped_file.h"
#include "google/protobuf/repeated_field.h"
#include "update_engine/common/action.h"
#include "update_engine/common/action_processor.h"
#include "update_engine/common/constants.h"
#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/update_metadata.pb.h"

namespace chromeos_update_engine {

namespace utils {

// Formats |vec_str| as a string of the form ["<elem1>", "<elem2>"].
// Does no escaping, only use this for presentation in error messages.
std::string StringVectorToString(const std::vector<std::string>& vec_str);

// Calculates the p2p file id from payload hash and size
std::string CalculateP2PFileId(const brillo::Blob& payload_hash,
                               size_t payload_size);

// 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 void* data, size_t 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);

bool WriteAll(const FileDescriptorPtr& fd, const void* buf, size_t count);
// WriteAll writes data at specified offset, but it modifies file position.
bool WriteAll(const FileDescriptorPtr& fd,
              const void* buf,
              size_t count,
              off_t off);

// https://man7.org/linux/man-pages/man2/pread.2.html
// PWriteAll writes data at specified offset, but it DOES NOT modify file
// position. Behaves similar to linux' pwrite syscall.
bool PWriteAll(const FileDescriptorPtr& fd,
               const void* buf,
               size_t count,
               off_t offset);

// Calls read() repeatedly until |count| bytes are read or EOF or EWOULDBLOCK
// is reached. Returns whether all read() calls succeeded (including EWOULDBLOCK
// as a success case), sets |eof| to whether the eof was reached and sets
// |out_bytes_read| to the actual number of bytes read regardless of the return
// value.
bool ReadAll(
    int fd, void* buf, size_t count, size_t* out_bytes_read, bool* eof);

// 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);

// Reads data at specified offset, this function does change file position.
bool ReadAll(const FileDescriptorPtr& fd,
             void* buf,
             size_t count,
             off_t offset,
             ssize_t* out_bytes_read);

// https://man7.org/linux/man-pages/man2/pread.2.html
// Reads data at specified offset, this function DOES NOT change file position.
// Behavior is similar to linux's pread syscall.
bool PReadAll(const FileDescriptorPtr& fd,
              void* buf,
              size_t count,
              off_t offset,
              ssize_t* out_bytes_read);

// Opens |path| for reading and appends its entire content to the container
// pointed to by |out_p|. Returns true upon successfully reading all of the
// file's content, false otherwise, in which case the state of the output
// container is unknown. ReadFileChunk starts reading the file from |offset|; if
// |size| is not -1, only up to |size| bytes are read in.
bool ReadFile(const std::string& path, brillo::Blob* out_p);
bool ReadFile(const std::string& path, std::string* out_p);
bool ReadFileChunk(const std::string& path,
                   off_t offset,
                   off_t size,
                   brillo::Blob* out_p);

// Invokes |cmd| in a pipe and appends its stdout to the container pointed to by
// |out_p|. Returns true upon successfully reading all of the output, false
// otherwise, in which case the state of the output container is unknown.
bool ReadPipe(const std::string& cmd, std::string* out_p);

// Returns the size of the block device at the file descriptor fd. If an error
// occurs, -1 is returned.
off_t BlockDevSize(int fd);

// Returns the size of the file at path, or the file descriptor fd. If the file
// is actually a block device, this function will automatically call
// BlockDevSize. If the file doesn't exist or some error occurrs, -1 is
// returned.
off_t FileSize(const std::string& path);
off_t FileSize(int fd);

bool SendFile(int out_fd, int in_fd, size_t count);

std::string ErrnoNumberAsString(int err);

// 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);

// Return true iff |path| exists and is a regular file
bool IsRegFile(const char* path);

// If |base_filename_template| is neither absolute (starts with "/") nor
// explicitly relative to the current working directory (starts with "./" or
// "../"), then it is prepended the system's temporary directory. On success,
// stores the name of the new temporary file in |filename|. If |fd| is
// non-null, the file descriptor returned by mkstemp is written to it and
// kept open; otherwise, it is closed. The template must end with "XXXXXX".
// Returns true on success.
bool MakeTempFile(const std::string& base_filename_template,
                  std::string* filename,
                  int* fd);

// Splits the partition device name into the block device name and partition
// number. For example, "/dev/sda3" will be split into {"/dev/sda", 3} and
// "/dev/mmcblk0p2" into {"/dev/mmcblk0", 2}
// Returns false when malformed device name is passed in.
// If both output parameters are omitted (null), can be used
// just to test the validity of the device name. Note that the function
// simply checks if the device name looks like a valid device, no other
// checks are performed (i.e. it doesn't check if the device actually exists).
bool SplitPartitionName(const std::string& partition_name,
                        std::string* out_disk_name,
                        int* out_partition_num);

// Builds a partition device name from the block device name and partition
// number. For example:
// {"/dev/sda", 1} => "/dev/sda1"
// {"/dev/mmcblk2", 12} => "/dev/mmcblk2p12"
// Returns empty string when invalid parameters are passed in
std::string MakePartitionName(const std::string& disk_name, int partition_num);

// Set the read-only attribute on the block device |device| to the value passed
// in |read_only|. Return whether the operation succeeded.
bool SetBlockDeviceReadOnly(const std::string& device, bool read_only);

// Synchronously mount or unmount a filesystem. Return true on success.
// When mounting, it will attempt to mount the device as the passed filesystem
// type |type|, with the passed |flags| options. If |type| is empty, "ext2",
// "ext3", "ext4" and "squashfs" will be tried.
bool MountFilesystem(const std::string& device,
                     const std::string& mountpoint,
                     unsigned long flags,  // NOLINT(runtime/int)
                     const std::string& type,
                     const std::string& fs_mount_options);
bool UnmountFilesystem(const std::string& mountpoint);

// Return whether the passed |mountpoint| path is a directory where a filesystem
// is mounted. Due to detection mechanism limitations, when used on directories
// where another part of the tree was bind mounted returns true only if bind
// mounted on top of a different filesystem (not inside the same filesystem).
bool IsMountpoint(const std::string& mountpoint);

// Returns a human-readable string with the file format based on magic constants
// on the header of the file.
std::string GetFileFormat(const std::string& path);

// Returns the string representation of the given UTC time.
// such as "11/14/2011 14:05:30 GMT".
std::string ToString(const base::Time utc_time);

// Returns true or false depending on the value of b.
std::string ToString(bool b);

// Returns a string representation of the given enum.
std::string ToString(DownloadSource source);

// Returns a string representation of the given enum.
std::string ToString(PayloadType payload_type);

// 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 uint8_t* const arr, const size_t length);
inline void HexDumpString(const std::string& str) {
  HexDumpArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
}
inline void HexDumpVector(const brillo::Blob& vect) {
  HexDumpArray(vect.data(), vect.size());
}

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;
  }
}

// Return the total number of blocks in the passed |extents| collection.
template <class T>
uint64_t BlocksInExtents(const T& extents) {
  uint64_t sum = 0;
  for (const auto& ext : extents) {
    sum += ext.num_blocks();
  }
  return sum;
}

// Converts seconds into human readable notation including days, hours, minutes
// and seconds. For example, 185 will yield 3m5s, 4300 will yield 1h11m40s, and
// 360000 will yield 4d4h0m0s.  Zero padding not applied. Seconds are always
// shown in the result.
std::string FormatSecs(unsigned secs);

// Converts a TimeDelta into human readable notation including days, hours,
// minutes, seconds and fractions of a second down to microsecond granularity,
// as necessary; for example, an output of 5d2h0m15.053s means that the input
// time was precise to the milliseconds only. Zero padding not applied, except
// for fractions. Seconds are always shown, but fractions thereof are only shown
// when applicable. If |delta| is negative, the output will have a leading '-'
// followed by the absolute duration.
std::string FormatTimeDelta(base::TimeDelta delta);

// This method transforms the given error code to be suitable for UMA and
// for error classification purposes by removing the higher order bits and
// aggregating error codes beyond the enum range, etc. This method is
// idempotent, i.e. if called with a value previously returned by this method,
// it'll return the same value again.
ErrorCode GetBaseErrorCode(ErrorCode code);

// Converts |time| to an Omaha InstallDate which is defined as "the
// number of PST8PDT calendar weeks since Jan 1st 2007 0:00 PST, times
// seven" with PST8PDT defined as "Pacific Time" (e.g. UTC-07:00 if
// daylight savings is observed and UTC-08:00 otherwise.)
//
// If the passed in |time| variable is before Monday January 1st 2007
// 0:00 PST, False is returned and the value returned in
// |out_num_days| is undefined. Otherwise the number of PST8PDT
// calendar weeks since that date times seven is returned in
// |out_num_days| and the function returns True.
//
// (NOTE: This function does not currently take daylight savings time
// into account so the result may up to one hour off. This is because
// the glibc date and timezone routines depend on the TZ environment
// variable and changing environment variables is not thread-safe.
bool ConvertToOmahaInstallDate(base::Time time, int* out_num_days);

// Look for the minor version value in the passed |store| and set
// |minor_version| to that value. Return whether the value was found and valid.
bool GetMinorVersion(const brillo::KeyValueStore& store,
                     uint32_t* minor_version);

// This function reads the specified data in |extents| into |out_data|. The
// extents are read from the file at |path|. |out_data_size| is the size of
// |out_data|. Returns false if the number of bytes to read given in
// |extents| does not equal |out_data_size|.
bool ReadExtents(const std::string& path,
                 const std::vector<Extent>& extents,
                 brillo::Blob* out_data,
                 ssize_t out_data_size,
                 size_t block_size);

bool WriteExtents(const std::string& path,
                  const google::protobuf::RepeatedPtrField<Extent>& extents,
                  const brillo::Blob& data,
                  size_t block_size);

constexpr bool ReadExtents(const std::string& path,
                           const std::vector<Extent>& extents,
                           brillo::Blob* out_data,
                           size_t block_size) {
  return ReadExtents(path,
                     extents,
                     out_data,
                     utils::BlocksInExtents(extents) * block_size,
                     block_size);
}

bool ReadExtents(const std::string& path,
                 const google::protobuf::RepeatedPtrField<Extent>& extents,
                 brillo::Blob* out_data,
                 size_t block_size);

// Read the current boot identifier and store it in |boot_id|. This identifier
// is constants during the same boot of the kernel and is regenerated after
// reboot. Returns whether it succeeded getting the boot_id.
bool GetBootId(std::string* boot_id);

// Gets a string value from the vpd for a given key using the `vpd_get_value`
// shell command. Returns true on success.
bool GetVpdValue(std::string key, std::string* result);

// This function gets the file path of the file pointed to by FileDiscriptor.
std::string GetFilePath(int fd);

// Divide |x| by |y| and round up to the nearest integer.
constexpr uint64_t DivRoundUp(uint64_t x, uint64_t y) {
  return (x + y - 1) / y;
}

// Round |x| up to be a multiple of |y|.
constexpr uint64_t RoundUp(uint64_t x, uint64_t y) {
  return DivRoundUp(x, y) * y;
}

// Returns the integer value of the first section of |version|. E.g. for
//  "10575.39." returns 10575. Returns 0 if |version| is empty, returns -1 if
// first section of |version| is invalid (e.g. not a number).
int VersionPrefix(const std::string& version);

// Parses a string in the form high.low, where high and low are 16 bit unsigned
// integers. If there is more than 1 dot, or if either of the two parts are
// not valid 16 bit unsigned numbers, then 0xffff is returned for both.
void ParseRollbackKeyVersion(const std::string& raw_version,
                             uint16_t* high_version,
                             uint16_t* low_version);

// Return a string representation of |utime| for log file names.
std::string GetTimeAsString(time_t utime);
// Returns the string format of the hashed |str_to_convert| that can be used
// with |Excluder| as the exclusion name.
std::string GetExclusionName(const std::string& str_to_convert);

// Parse `old_version` and `new_version` as integer timestamps and
// Return kSuccess if `new_version` is larger/newer.
// Return kSuccess if either one is empty.
// Return kError if |old_version| is not empty and not an integer.
// Return kDownloadManifestParseError if |new_version| is not empty and not an
// integer.
// Return kPayloadTimestampError if both are integers but |new_version| <
// |old_version|.
ErrorCode IsTimestampNewer(const std::string& old_version,
                           const std::string& new_version);

std::unique_ptr<android::base::MappedFile> GetReadonlyZeroBlock(size_t size);

std::string_view GetReadonlyZeroString(size_t size);

}  // namespace utils

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

 private:
  int* fd_;
  bool should_close_ = true;
  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), should_remove_(true) {}
  ~ScopedPathUnlinker() {
    if (should_remove_ && unlink(path_.c_str()) < 0) {
      PLOG(ERROR) << "Unable to unlink path " << path_;
    }
  }
  void set_should_remove(bool should_remove) { should_remove_ = should_remove; }

 private:
  const std::string path_;
  bool should_remove_;
  DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker);
};

class ScopedTempFile {
 public:
  ScopedTempFile() : ScopedTempFile("update_engine_temp.XXXXXX") {}

  // If |open_fd| is true, a writable file descriptor will be opened for this
  // file.
  // If |truncate_size| is non-zero, truncate file to that size on creation.
  explicit ScopedTempFile(const std::string& pattern,
                          bool open_fd = false,
                          size_t truncate_size = 0) {
    CHECK(utils::MakeTempFile(pattern, &path_, open_fd ? &fd_ : nullptr));
    unlinker_.reset(new ScopedPathUnlinker(path_));
    if (open_fd) {
      CHECK_GE(fd_, 0);
      fd_closer_.reset(new ScopedFdCloser(&fd_));
    }
    if (truncate_size > 0) {
      CHECK_EQ(0, truncate(path_.c_str(), truncate_size));
    }
  }
  virtual ~ScopedTempFile() = default;

  const std::string& path() const { return path_; }
  int fd() const {
    CHECK(fd_closer_);
    return fd_;
  }
  void CloseFd() {
    CHECK(fd_closer_);
    fd_closer_.reset();
  }

 private:
  std::string path_;
  std::unique_ptr<ScopedPathUnlinker> unlinker_;

  int fd_{-1};
  std::unique_ptr<ScopedFdCloser> fd_closer_;

  DISALLOW_COPY_AND_ASSIGN(ScopedTempFile);
};

// 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_(ErrorCode::kError),
        should_complete_(true) {
    CHECK(processor_);
  }
  ~ScopedActionCompleter() {
    if (should_complete_)
      processor_->ActionComplete(action_, code_);
  }
  void set_code(ErrorCode code) { code_ = code; }
  void set_should_complete(bool should_complete) {
    should_complete_ = should_complete;
  }
  ErrorCode get_code() const { return code_; }

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

// Simple wrapper for creating a slice of some container,
// similar to string_view but for other containers.
template <typename T>
struct Range {
  Range(T t1, T t2) : t1_(t1), t2_(t2) {}
  constexpr auto begin() const noexcept { return t1_; }
  constexpr auto end() const noexcept { return t2_; }
  T t1_;
  T t2_;
};

std::string HexEncode(const brillo::Blob& blob) noexcept;
std::string HexEncode(const std::string_view blob) noexcept;

template <size_t kSize>
std::string HexEncode(const std::array<uint8_t, kSize> blob) noexcept {
  return base::HexEncode(blob.data(), blob.size());
}

}  // namespace chromeos_update_engine

#define TEST_AND_RETURN_FALSE_ERRNO(_x)                              \
  do {                                                               \
    bool _success = static_cast<bool>(_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 = static_cast<bool>(_x); \
    if (!_success) {                       \
      LOG(ERROR) << #_x " failed.";        \
      return false;                        \
    }                                      \
  } while (0)

#define TEST_AND_RETURN_ERRNO(_x)                                    \
  do {                                                               \
    bool _success = static_cast<bool>(_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 = static_cast<bool>(_x); \
    if (!_success) {                       \
      LOG(ERROR) << #_x " failed.";        \
      return;                              \
    }                                      \
  } while (0)

#define TEST_AND_RETURN_FALSE_ERRCODE(_x)      \
  do {                                         \
    errcode_t _error = (_x);                   \
    if (_error) {                              \
      errno = _error;                          \
      LOG(ERROR) << #_x " failed: " << _error; \
      return false;                            \
    }                                          \
  } while (0)

#define TEST_OP(_x, _y, op)                                                \
  do {                                                                     \
    const auto& x = _x;                                                    \
    const auto& y = _y;                                                    \
    if (!(x op y)) {                                                       \
      LOG(ERROR) << #_x " " #op " " #_y << " failed: " << x << " " #op " " \
                 << y;                                                     \
      return {};                                                           \
    }                                                                      \
  } while (0)

#define TEST_EQ(_x, _y) TEST_OP(_x, _y, ==)
#define TEST_NE(_x, _y) TEST_OP(_x, _y, !=)
#define TEST_LE(_x, _y) TEST_OP(_x, _y, <=)
#define TEST_GE(_x, _y) TEST_OP(_x, _y, >=)
#define TEST_LT(_x, _y) TEST_OP(_x, _y, <)
#define TEST_GT(_x, _y) TEST_OP(_x, _y, >)

#endif  // UPDATE_ENGINE_COMMON_UTILS_H_
