// Copyright 2017 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/ash/logging.h"

#include <cstdio>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/platform_file.h"
#include "base/files/scoped_file.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/system/sys_info.h"
#include "base/task/thread_pool.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/zygote_host/zygote_host_linux.h"

namespace ash {

namespace {

// This is true when logging redirect was tried for the first user in the
// session.
bool g_chrome_logging_redirect_tried = false;

// This should be set to true for tests that rely on log redirection.
bool g_force_log_redirection = false;

template <typename ProcessHost>
void ReinitializeLoggingForProcessHost(ProcessHost* process_host,
                                       const logging::LoggingSettings& settings,
                                       base::PlatformFile raw_log_file_fd) {
  static_assert(std::is_same<content::ChildProcessHost, ProcessHost>() ||
                std::is_same<content::RenderProcessHost, ProcessHost>());

  base::ScopedFD log_file_descriptor(HANDLE_EINTR(dup(raw_log_file_fd)));
  if (log_file_descriptor.get() < 0) {
    DLOG(WARNING) << "Unable to duplicate log file handle";
    return;
  }

  process_host->ReinitializeLogging(settings.logging_dest,
                                    std::move(log_file_descriptor));
}

void LogFileSetUp(const base::CommandLine& command_line,
                  const base::FilePath& log_path,
                  const base::FilePath& target_path) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // The |log_path| is the new log file after log rotation. so it shouldn't be
  // deleted even if it already exists.
  logging::LoggingSettings settings;
  settings.logging_dest = logging::DetermineLoggingDestination(command_line);
  settings.log_file_path = log_path.value().c_str();
  if (!logging::InitLogging(settings)) {
    DLOG(ERROR) << "Unable to initialize logging to " << log_path.value();
    base::ThreadPool::PostTask(
        FROM_HERE, {base::MayBlock()},
        base::BindOnce(&logging::RemoveSymlinkAndLog, log_path, target_path));
    return;
  }

  base::ScopedFILE log_file(logging::DuplicateLogFILE());
  base::PlatformFile log_file_fd = fileno(log_file.get());
  if (log_file_fd < 0) {
    DLOG(WARNING) << "Unable to duplicate log file handle";
    return;
  }

  // Redirect Zygote and future children's logs.
  content::ZygoteHost::GetInstance()->ReinitializeLogging(settings.logging_dest,
                                                          log_file_fd);

  // Redirect child processes' logs.
  for (content::BrowserChildProcessHostIterator it; !it.Done(); ++it)
    ReinitializeLoggingForProcessHost(it.GetHost(), settings, log_file_fd);

  for (auto it(content::RenderProcessHost::AllHostsIterator()); !it.IsAtEnd();
       it.Advance()) {
    ReinitializeLoggingForProcessHost(it.GetCurrentValue(), settings,
                                      log_file_fd);
  }
}

}  // namespace

void ForceLogRedirectionForTesting() {
  g_force_log_redirection = true;
}

void RedirectChromeLogging(const base::CommandLine& command_line) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // Only redirect when on an actual device. To do otherwise conflicts with
  // --vmodule that developers may want to use.
  if (!base::SysInfo::IsRunningOnChromeOS() && !g_force_log_redirection)
    return;

  if (g_chrome_logging_redirect_tried) {
    LOG(WARNING) << "NOT redirecting logging for multi-profiles case.";
    return;
  }

  g_chrome_logging_redirect_tried = true;

  if (command_line.HasSwitch(switches::kDisableLoggingRedirect))
    return;

  // Redirect logs to the session log directory, if set.  Otherwise
  // defaults to the profile dir.
  const base::FilePath log_path = logging::GetSessionLogFile(command_line);

  LOG(WARNING) << "Redirecting post-login logging to " << log_path.value();

  // Rotate the old log files when redirecting.
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock()},
      base::BindOnce(&logging::SetUpLogFile, log_path, /*new_log=*/true),
      base::BindOnce(&LogFileSetUp, command_line, log_path));
}

}  // namespace ash
