//
// 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_UTILS_H_
#define UPDATE_ENGINE_UTILS_H_

#include <errno.h>
#include <unistd.h>

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

#include <base/files/file_path.h>
#include <base/posix/eintr_wrapper.h>
#include <base/time/time.h>
#include <chromeos/key_value_store.h>
#include <chromeos/secure_blob.h>
#include "metrics/metrics_library.h"

#include "update_engine/action.h"
#include "update_engine/action_processor.h"
#include "update_engine/connection_manager_interface.h"
#include "update_engine/constants.h"
#include "update_engine/file_descriptor.h"
#include "update_engine/metrics.h"
#include "update_engine/update_metadata.pb.h"

namespace chromeos_update_engine {

class SystemState;

namespace utils {

// Converts a struct timespec representing a number of seconds since
// the Unix epoch to a base::Time. Sub-microsecond time is rounded
// down.
base::Time TimeFromStructTimespec(struct timespec *ts);

// 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 std::string& payload_hash,
                               size_t payload_size);

// Parse the firmware version from one line of output from the
// "mosys" command.
std::string ParseECVersion(std::string input_line);

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

bool WriteAll(FileDescriptorPtr fd, const void* buf, size_t count);
bool PWriteAll(FileDescriptorPtr 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);

bool PReadAll(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, chromeos::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,
                   chromeos::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 path, or the file descriptor fd. If
// an error occurs, -1 is returned.
off_t BlockDevSize(const std::string& path);
off_t BlockDevSize(int fd);

// Returns the size of the file at path, or the file desciptor 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);

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

// Try attaching UBI |volume_num|. If there is any error executing required
// commands to attach the volume, this function returns false. This function
// only returns true if "/dev/ubi%d_0" becomes available in |timeout| seconds.
bool TryAttachingUbiVolume(int volume_num, int timeout);

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

// If |base_dirname_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 directory in |dirname|. The template
// must end with "XXXXXX". Returns true on success.
bool MakeTempDirectory(const std::string& base_dirname_template,
                       std::string* dirname);

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

// Similar to "MakePartitionName" but returns a name that is suitable for
// mounting. On NAND system we can write to "/dev/ubiX_0", which is what
// MakePartitionName returns, but we cannot mount that device. To mount, we
// have to use "/dev/ubiblockX_0" for rootfs. Stateful and OEM partitions are
// mountable with "/dev/ubiX_0". The input is a partition device such as
// /dev/sda3. Return empty string on error.
std::string MakePartitionNameForMount(const std::string& part_name);

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

// Returns the block count and the block byte size of the 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);

// Determines the block count and block size of the ext3 fs. At least 2048 bytes
// are required to parse the first superblock. Returns whether the buffer
// contains a valid ext3 filesystem and the values were parsed.
bool GetExt3Size(const uint8_t* buffer, size_t buffer_size,
                 int* out_block_count,
                 int* out_block_size);

// Determines the block count and block size of the squashfs v4 fs. At least 96
// bytes are required to parse the header of the filesystem. Since squashfs
// doesn't define a physical block size, a value of 4096 is used for the block
// size, which is the default padding when creating the filesystem.
// Returns whether the buffer contains a valid squashfs v4 header and the size
// was parsed. Only little endian squashfs is supported.
bool GetSquashfs4Size(const uint8_t* buffer, size_t buffer_size,
                      int* out_block_count,
                      int* out_block_size);

// Returns whether the filesystem is an ext[234] filesystem. In case of failure,
// such as if the file |device| doesn't exists or can't be read, it returns
// false.
bool IsExtFilesystem(const std::string& device);

// Returns whether the filesystem is a squashfs filesystem. In case of failure,
// such as if the file |device| doesn't exists or can't be read, it returns
// false.
bool IsSquashfsFilesystem(const std::string& device);

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

// Schedules a Main Loop callback to trigger the crash reporter to perform an
// upload as if this process had crashed.
void ScheduleCrashReporterUpload();

// 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 chromeos::Blob& vect) {
  HexDumpArray(vect.data(), vect.size());
}

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

// Cgroups cpu shares constants. 1024 is the default shares a standard process
// gets and 2 is the minimum value. We set High as a value that gives the
// update-engine 2x the cpu share of a standard process.
enum CpuShares {
  kCpuSharesHigh = 2048,
  kCpuSharesNormal = 1024,
  kCpuSharesLow = 2,
};

// Sets the current process shares to |shares|. Returns true on
// success, false otherwise.
bool SetCpuShares(CpuShares shares);

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

// Transforms a ErrorCode value into a metrics::DownloadErrorCode.
// This obviously only works for errors related to downloading so if |code|
// is e.g. |ErrorCode::kFilesystemCopierError| then
// |kDownloadErrorCodeInputMalformed| is returned.
metrics::DownloadErrorCode GetDownloadErrorCode(ErrorCode code);

// Transforms a ErrorCode value into a metrics::AttemptResult.
//
// If metrics::AttemptResult::kPayloadDownloadError is returned, you
// can use utils::GetDownloadError() to get more detail.
metrics::AttemptResult GetAttemptResult(ErrorCode code);

// Calculates the internet connection type given |type| and |tethering|.
metrics::ConnectionType GetConnectionType(NetworkConnectionType type,
                                          NetworkTethering tethering);

// Returns a string representation of the ErrorCodes (either the base
// error codes or the bit flags) for logging purposes.
std::string CodeToString(ErrorCode code);

// Creates the powerwash marker file with the appropriate commands in it.  Uses
// |file_path| as the path to the marker file if non-null, otherwise uses the
// global default. Returns true if successfully created.  False otherwise.
bool CreatePowerwashMarkerFile(const char* file_path);

// Deletes the marker file used to trigger Powerwash using clobber-state.  Uses
// |file_path| as the path to the marker file if non-null, otherwise uses the
// global default. Returns true if successfully deleted. False otherwise.
bool DeletePowerwashMarkerFile(const char* file_path);

// Decodes the data in |base64_encoded| and stores it in a temporary
// file. Returns false if the given data is empty, not well-formed
// base64 or if an error occurred. If true is returned, the decoded
// data is stored in the file returned in |out_path|. The file should
// be deleted when no longer needed.
bool DecodeAndStoreBase64String(const std::string& base64_encoded,
                                base::FilePath *out_path);

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

// This function returns the duration on the wallclock since the last
// time it was called for the same |state_variable_key| value.
//
// If the function returns |true|, the duration (always non-negative)
// is returned in |out_duration|. If the function returns |false|
// something went wrong or there was no previous measurement.
bool WallclockDurationHelper(SystemState* system_state,
                             const std::string& state_variable_key,
                             base::TimeDelta* out_duration);

// This function returns the duration on the monotonic clock since the
// last time it was called for the same |storage| pointer.
//
// You should pass a pointer to a 64-bit integer in |storage| which
// should be initialized to 0.
//
// If the function returns |true|, the duration (always non-negative)
// is returned in |out_duration|. If the function returns |false|
// something went wrong or there was no previous measurement.
bool MonotonicDurationHelper(SystemState* system_state,
                             int64_t* storage,
                             base::TimeDelta* out_duration);

// 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 chromeos::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,
                 chromeos::Blob* out_data, ssize_t out_data_size,
                 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);

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

// 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_(ErrorCode::kError),
        should_complete_(true) {}
  ~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);
};

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

#endif  // UPDATE_ENGINE_UTILS_H_
