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

#include "image-burner/image_burner_utils.h"

#include <memory>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/memory/free_deleter.h>
#include <base/strings/stringprintf.h>
#include <rootdev/rootdev.h>

namespace imageburn {
namespace {

const int kFsyncRatio = 1024;

bool RealPath(const char* path, std::string* real_path) {
  std::unique_ptr<char, base::FreeDeleter> result(realpath(path, nullptr));
  if (!result) {
    PLOG(ERROR) << "Couldn't get real path of " << path;
    return false;
  }
  *real_path = result.get();
  return true;
}

}  // namespace

BurnWriter::BurnWriter()
    : fstat_callback_(base::BindRepeating(&base::File::Fstat)) {}

bool BurnWriter::Open(const char* path) {
  if (file_.IsValid())
    return false;

  file_.Initialize(base::FilePath(path),
                   base::File::FLAG_WRITE | base::File::FLAG_OPEN);
  if (!file_.IsValid()) {
    PLOG(ERROR) << "Couldn't open target path " << path;
    return false;
  }

  base::stat_wrapper_t st = {};
  if (fstat_callback_.Run(file_.GetPlatformFile(), &st) != 0) {
    PLOG(ERROR) << "Unable to stat file for path " << path;
    Close();
    return false;
  }

  if (!S_ISBLK(st.st_mode)) {
    PLOG(ERROR) << "Attempt to write to non-block device " << path;
    Close();
    return false;
  }

  LOG(INFO) << path << " opened";
  return true;
}

bool BurnWriter::Close() {
  if (!file_.IsValid())
    return false;
  file_.Close();
  return true;
}

int BurnWriter::Write(const char* data_block, int data_size) {
  const int written = file_.WriteAtCurrentPos(data_block, data_size);
  if (written != data_size) {
    PLOG(ERROR) << "Error writing to target file";
    return written;
  }

  if (!writes_count_ && !file_.Flush()) {
    PLOG(ERROR) << "Error flushing target file.";
    return -1;
  }

  writes_count_++;
  if (writes_count_ == kFsyncRatio)
    writes_count_ = 0;

  return written;
}

BurnReader::BurnReader() {}

bool BurnReader::Open(const char* path) {
  if (file_.IsValid())
    return false;

  file_.Initialize(base::FilePath(path),
                   base::File::FLAG_READ | base::File::FLAG_OPEN);
  if (!file_.IsValid()) {
    PLOG(ERROR) << "Couldn't open source path " << path;
    return false;
  }

  // Obtains the real path of the file associated with the opened file
  // descriptor by resolving the /proc/self/fd/<descriptor> symlink. Compares
  // |path| against the real path determined by /proc/self/fd/<descriptor> to
  // make sure |path| specifies the real path and avoids a potential TOCTOU
  // race between the underlying realpath() and open() call.
  int fd = file_.GetPlatformFile();
  std::string fd_path;
  if (!RealPath(base::StringPrintf("/proc/self/fd/%d", fd).c_str(), &fd_path)) {
    file_.Close();
    return false;
  }
  if (fd_path != path) {
    LOG(ERROR) << path << " isn't a fully resolved path";
    file_.Close();
    return false;
  }

  LOG(INFO) << path << " opened";
  return true;
}

bool BurnReader::Close() {
  if (!file_.IsValid())
    return false;
  file_.Close();
  return true;
}

int BurnReader::Read(char* data_block, int data_size) {
  const int read = file_.ReadAtCurrentPos(data_block, data_size);
  if (read < 0)
    PLOG(ERROR) << "Error reading from source file";
  return read;
}

int64_t BurnReader::GetSize() {
  if (!file_.IsValid())
    return -1;
  return file_.GetLength();
}

bool BurnPathGetter::GetRealPath(const char* path, std::string* real_path) {
  return RealPath(path, real_path);
}

bool BurnPathGetter::GetRootPath(std::string* path) {
  char root_path[PATH_MAX];
  if (rootdev(root_path, sizeof(root_path), true, true)) {
    // Coult not get root path.
    return false;
  }
  *path = root_path;
  return true;
}

}  // namespace imageburn
