// Copyright 2018 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 "chaps/system_shutdown_blocker.h"

#include <string>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/location.h>
#include <base/strings/stringprintf.h>

namespace chaps {

SystemShutdownBlocker::SystemShutdownBlocker(
    const scoped_refptr<base::SingleThreadTaskRunner>&
        origin_thread_task_runner)
    : origin_thread_task_runner_(origin_thread_task_runner) {}

SystemShutdownBlocker::~SystemShutdownBlocker() {
  for (int slot_id : blocked_slots_)
    PerformUnblock(slot_id);
  blocked_slots_.clear();
}

void SystemShutdownBlocker::Block(int slot_id,
                                  base::TimeDelta fallback_timeout) {
  // Post block task.
  auto perform_block_task = base::Bind(&SystemShutdownBlocker::PerformBlock,
                                       base::Unretained(this), slot_id);
  origin_thread_task_runner_->PostTask(FROM_HERE, perform_block_task);

  // Post delayed unblock task (fallback).
  auto perform_unblock_task =
      base::Bind(&SystemShutdownBlocker::PerformUnblockIfBlocked,
                 base::Unretained(this), slot_id);
  origin_thread_task_runner_->PostDelayedTask(FROM_HERE, perform_unblock_task,
                                              fallback_timeout);
}

void SystemShutdownBlocker::Unblock(int slot_id) {
  // Post unblock task.
  auto perform_unblock_task =
      base::Bind(&SystemShutdownBlocker::PerformUnblockIfBlocked,
                 base::Unretained(this), slot_id);
  origin_thread_task_runner_->PostTask(FROM_HERE, perform_unblock_task);
}

void SystemShutdownBlocker::PerformBlock(int slot_id) {
  // Create lock file with chapsd PID as content and readable for powerd.
  const base::FilePath lock_path = GetPowerdLockFilePath(slot_id);
  if (!base::DirectoryExists(lock_path.DirName())) {
    LOG(ERROR) << "Failed to create lock file (" << lock_path.DirName().value()
               << " doesn't exist)";
    return;
  }
  blocked_slots_.insert(slot_id);

  base::File lock_file(lock_path,
                       base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
  std::string lock_contents = base::StringPrintf("%d", getpid());
  int mode = base::FILE_PERMISSION_READ_BY_USER |
             base::FILE_PERMISSION_WRITE_BY_USER |
             base::FILE_PERMISSION_READ_BY_GROUP |
             base::FILE_PERMISSION_READ_BY_OTHERS;  // chmod 644
  if (!lock_file.IsValid() ||
      lock_file.WriteAtCurrentPos(lock_contents.data(), lock_contents.size()) <
          0 ||
      !base::SetPosixFilePermissions(lock_path, mode)) {
    PLOG(ERROR) << "Failed to create lock file.";
    return;
  }
  LOG(INFO) << "Created lock file: " << lock_path.value();
}

void SystemShutdownBlocker::PerformUnblockIfBlocked(int slot_id) {
  if (blocked_slots_.count(slot_id) && PerformUnblock(slot_id))
    blocked_slots_.erase(slot_id);
}

bool SystemShutdownBlocker::PerformUnblock(int slot_id) {
  const base::FilePath lock_path = GetPowerdLockFilePath(slot_id);
  if (!base::PathExists(lock_path)) {
    LOG(WARNING) << "Couldn't delete lock file (not existant): "
                 << lock_path.value();
    return true;
  }
  if (!base::DeleteFile(lock_path)) {
    PLOG(ERROR) << "Couldn't delete lock file: " << lock_path.value();
    return false;
  }
  LOG(INFO) << "Deleted lock file: " << lock_path.value();
  return true;
}

base::FilePath SystemShutdownBlocker::GetPowerdLockFilePath(int slot_id) const {
  return base::FilePath("/run/lock/power_override/chapsd_token_init_slot_" +
                        std::to_string(slot_id) + ".lock");
}

}  // namespace chaps
