// Copyright 2017 The Chromium 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 "components/update_client/action_runner.h"

#include <tuple>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "components/update_client/component.h"
#include "components/update_client/configurator.h"
#include "components/update_client/task_traits.h"

namespace {

const base::FilePath::CharType kRecoveryFileName[] =
    FILE_PATH_LITERAL("ChromeRecovery.exe");

}  // namespace

namespace update_client {

void ActionRunner::RunCommand(const base::CommandLine& cmdline) {
  base::LaunchOptions options;
  options.start_hidden = true;
  base::Process process = base::LaunchProcess(cmdline, options);

  base::PostTaskWithTraits(
      FROM_HERE, kTaskTraitsRunCommand,
      base::BindOnce(&ActionRunner::WaitForCommand, base::Unretained(this),
                     std::move(process)));
}

void ActionRunner::WaitForCommand(base::Process process) {
  int exit_code = 0;
  const base::TimeDelta kMaxWaitTime = base::TimeDelta::FromSeconds(600);
  const bool succeeded =
      process.WaitForExitWithTimeout(kMaxWaitTime, &exit_code);
  base::DeleteFile(unpack_path_, true);
  main_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(std::move(run_complete_), succeeded, exit_code, 0));
}

base::CommandLine ActionRunner::MakeCommandLine(
    const base::FilePath& unpack_path) const {
  base::CommandLine command_line(unpack_path.Append(kRecoveryFileName));
  if (!is_per_user_install_)
    command_line.AppendSwitch("system");
  command_line.AppendSwitchASCII(
      "browser-version", component_.config()->GetBrowserVersion().GetString());
  command_line.AppendSwitchASCII("sessionid", component_.session_id());
  const auto app_guid = component_.config()->GetAppGuid();
  if (!app_guid.empty())
    command_line.AppendSwitchASCII("appguid", app_guid);
  VLOG(1) << "run action: " << command_line.GetCommandLineString();
  return command_line;
}

void ActionRunner::RunRecoveryCRXElevated(const base::FilePath& crx_path) {
  base::CreateCOMSTATaskRunnerWithTraits(
      kTaskTraitsRunCommand, base::SingleThreadTaskRunnerThreadMode::DEDICATED)
      ->PostTask(FROM_HERE,
                 base::BindOnce(&ActionRunner::RunRecoveryCRXElevatedInSTA,
                                base::Unretained(this), crx_path));
}

void ActionRunner::RunRecoveryCRXElevatedInSTA(const base::FilePath& crx_path) {
  bool succeeded = false;
  int error_code = 0;
  int extra_code = 0;
  const auto config = component_.config();
  std::tie(succeeded, error_code, extra_code) =
      component_.config()->GetRecoveryCRXElevator().Run(
          crx_path, config->GetAppGuid(),
          config->GetBrowserVersion().GetString(), component_.session_id());
  main_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(std::move(run_complete_), succeeded, error_code,
                                extra_code));
}

}  // namespace update_client
