// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/sandbox/sandbox_handler.h"

#include <utility>

#include "base/functional/bind.h"
#include "base/numerics/safe_conversions.h"
#include "base/values.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/process_type.h"
#include "sandbox/policy/features.h"
#include "sandbox/policy/win/sandbox_win.h"

using content::BrowserChildProcessHostIterator;
using content::ChildProcessData;
using content::RenderProcessHost;

namespace sandbox_handler {
namespace {

base::Value::List FetchBrowserChildProcesses() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  base::Value::List browser_processes;

  for (BrowserChildProcessHostIterator itr; !itr.Done(); ++itr) {
    const ChildProcessData& process_data = itr.GetData();
    // Only add processes that have already started, i.e. with valid handles.
    if (!process_data.GetProcess().IsValid())
      continue;
    base::Value::Dict proc;
    proc.Set("processId",
             base::strict_cast<double>(process_data.GetProcess().Pid()));
    proc.Set("processType",
             content::GetProcessTypeNameInEnglish(process_data.process_type));
    proc.Set("name", process_data.name);
    proc.Set("metricsName", process_data.metrics_name);
    proc.Set("sandboxType",
             sandbox::policy::SandboxWin::GetSandboxTypeInEnglish(
                 process_data.sandbox_type));
    browser_processes.Append(std::move(proc));
  }

  return browser_processes;
}

base::Value::List FetchRenderHostProcesses() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  base::Value::List renderer_processes;

  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
       !it.IsAtEnd(); it.Advance()) {
    RenderProcessHost* host = it.GetCurrentValue();
    // Skip processes that might not have started yet.
    if (!host->GetProcess().IsValid())
      continue;

    base::Value::Dict proc;
    proc.Set("processId", base::strict_cast<double>(host->GetProcess().Pid()));
    renderer_processes.Append(std::move(proc));
  }

  return renderer_processes;
}

base::Value::Dict FeatureToValue(const base::Feature& feature) {
  base::Value::Dict feature_info;
  feature_info.Set("name", feature.name);
  feature_info.Set("enabled", base::FeatureList::IsEnabled(feature));
  return feature_info;
}

base::Value::List FetchSandboxFeatures() {
  base::Value::List features;
  features.Append(FeatureToValue(sandbox::policy::features::kGpuAppContainer));
  features.Append(FeatureToValue(sandbox::policy::features::kGpuLPAC));
  features.Append(
      FeatureToValue(sandbox::policy::features::kNetworkServiceSandbox));
  features.Append(
      FeatureToValue(sandbox::policy::features::kRendererAppContainer));
  features.Append(
      FeatureToValue(sandbox::policy::features::kWinSboxAllowSystemFonts));
  features.Append(FeatureToValue(
      sandbox::policy::features::kWinSboxDisableExtensionPoints));
  return features;
}

}  // namespace

SandboxHandler::SandboxHandler() = default;
SandboxHandler::~SandboxHandler() = default;

void SandboxHandler::RegisterMessages() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  web_ui()->RegisterMessageCallback(
      "requestSandboxDiagnostics",
      base::BindRepeating(&SandboxHandler::HandleRequestSandboxDiagnostics,
                          base::Unretained(this)));
}

void SandboxHandler::HandleRequestSandboxDiagnostics(
    const base::Value::List& args) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  CHECK_EQ(1U, args.size());
  sandbox_diagnostics_callback_id_ = args[0].Clone();

  AllowJavascript();

  browser_processes_ = FetchBrowserChildProcesses();

  sandbox::policy::SandboxWin::GetPolicyDiagnostics(
      base::BindOnce(&SandboxHandler::FetchSandboxDiagnosticsCompleted,
                     weak_ptr_factory_.GetWeakPtr()));
}

// This runs nested inside SandboxWin so we get out quickly.
void SandboxHandler::FetchSandboxDiagnosticsCompleted(
    base::Value sandbox_policies) {
  sandbox_policies_ = std::move(sandbox_policies);
  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(&SandboxHandler::GetRendererProcessesAndFinish,
                                weak_ptr_factory_.GetWeakPtr()));
}

void SandboxHandler::GetRendererProcessesAndFinish() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  auto renderer_processes = FetchRenderHostProcesses();
  base::Value::Dict results;
  results.Set("browser", std::move(browser_processes_));
  results.Set("policies", std::move(sandbox_policies_));
  results.Set("renderer", std::move(renderer_processes));
  results.Set("features", FetchSandboxFeatures());
  ResolveJavascriptCallback(sandbox_diagnostics_callback_id_,
                            std::move(results));
}

}  // namespace sandbox_handler
