// Copyright 2021 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 "arc/data-snapshotd/block_ui_controller.h"

#include <stdlib.h>

#include <utility>

#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/process/launch.h>
#include <base/time/time.h>
#include <brillo/process/process.h>

namespace arc {
namespace data_snapshotd {

namespace {

constexpr base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(20);

constexpr char kDisplayBinary[] = "chromeos-boot-alert";

// Environment variables and values:
constexpr char kMessageOptions[] = "MESSAGE_OPTIONS";
constexpr char kMarkup[] = "--markup";
constexpr char kTmpDir[] = "TMPDIR";
constexpr char kTmpDirValue[] = "/var/cache/arc-data-snapshot/tmp/";
constexpr char kImageBackgroundRgb[] = "IMAGE_BACKGROUND_RGB";
constexpr char kImageBackgroundRgbValue[] = "fefefe";
constexpr char kImageTextColor[] = "IMAGE_TEXT_COLOR";
constexpr char kImageTextColorValue[] = "Black";
constexpr char kAssetsImagePath[] = "ASSETS_IMAGE_PATH";
constexpr char kAssetsImagePathValue[] = "images";
constexpr char kProgressBarWidth[] = "PROGRESS_BAR_WIDTH";
constexpr char kProgressBarWidthValue[] = "1";
constexpr char kProgressBarRgb[] = "PROGRESS_BAR_RGB";
constexpr char kProgressBarRgbValue[] = "1A73E8";

bool LaunchProcessImpl(const base::CommandLine& cmd,
                       const base::LaunchOptions& options) {
  int exit_code;
  auto p = base::LaunchProcess(cmd, options);
  if (!p.WaitForExitWithTimeout(kTimeout, &exit_code) ||
      exit_code != EXIT_SUCCESS) {
    return false;
  }
  return true;
}

}  // namespace

base::CommandLine GetShowScreenCommandLine() {
  base::CommandLine cmd{base::FilePath(kDisplayBinary)};
  cmd.AppendArg("update_arc_data_snapshot");
  return cmd;
}

base::CommandLine GetUpdateProgressCommandLine(int percent) {
  base::CommandLine cmd{base::FilePath(kDisplayBinary)};
  cmd.AppendArg("update_progress");
  cmd.AppendArg(std::to_string(percent));
  return cmd;
}

base::LaunchOptions GetShowScreenOptions(const base::FilePath& snapshot_dir) {
  base::EnvironmentMap env;
  env[kMessageOptions] = kMarkup;
  env[kTmpDir] = kTmpDirValue;
  env[kAssetsImagePath] = snapshot_dir.Append(kAssetsImagePathValue).value();
  env[kImageBackgroundRgb] = kImageBackgroundRgbValue;
  env[kImageTextColor] = kImageTextColorValue;

  base::LaunchOptions options;
  options.environment = std::move(env);
  return options;
}

base::LaunchOptions GetUpdateProgressOptions() {
  base::EnvironmentMap env;
  env[kProgressBarWidth] = kProgressBarWidthValue;
  env[kProgressBarRgb] = kProgressBarRgbValue;
  env[kImageBackgroundRgb] = kImageBackgroundRgbValue;

  base::LaunchOptions options;
  options.environment = std::move(env);
  return options;
}

BlockUiController::BlockUiController(std::unique_ptr<EscKeyWatcher> watcher,
                                     const base::FilePath& snapshot_dir)
    : BlockUiController(std::move(watcher),
                        snapshot_dir,
                        base::BindRepeating(&LaunchProcessImpl)) {}

BlockUiController::~BlockUiController() {}

// static
std::unique_ptr<BlockUiController> BlockUiController::CreateForTesting(
    std::unique_ptr<EscKeyWatcher> watcher,
    const base::FilePath& snapshot_dir,
    LaunchProcessCallback callback) {
  return base::WrapUnique(new BlockUiController(
      std::move(watcher), snapshot_dir, std::move(callback)));
}

bool BlockUiController::ShowScreen() {
  if (shown_) {
    LOG(INFO) << "UI screen is present.";
    return true;
  }
  LOG(INFO) << "Showing UI Screen";

  // Once the screen is shown, it stays so until the daemon is stopped.
  shown_ = launch_process_callback_.Run(GetShowScreenCommandLine(),
                                        GetShowScreenOptions(snapshot_dir_));
  if (!shown_)
    LOG(ERROR) << "Failed to launch update_arc_data_snapshot screen";

  watcher_->Init();
  return shown_;
}

bool BlockUiController::UpdateProgress(int percent) {
  if (!ShowScreen()) {
    LOG(ERROR) << "Failed to start update_arc_data_snapshot_screen.";
    return false;
  }
  DCHECK(shown_);

  if (!launch_process_callback_.Run(GetUpdateProgressCommandLine(percent),
                                    GetUpdateProgressOptions())) {
    LOG(ERROR) << "Failed to update update_arc_data_snapshot";
    return false;
  }
  return true;
}

BlockUiController::BlockUiController(std::unique_ptr<EscKeyWatcher> watcher,
                                     const base::FilePath& snapshot_dir,
                                     LaunchProcessCallback callback)
    : watcher_(std::move(watcher)),
      snapshot_dir_(snapshot_dir),
      launch_process_callback_(std::move(callback)) {
  DCHECK(watcher_);
}

}  // namespace data_snapshotd
}  // namespace arc
