// Copyright 2014 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 "chrome/browser/metrics/first_web_contents_profiler.h"

#include <string>

#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/browser_side_navigation_policy.h"

namespace {

class FirstWebContentsProfiler : public content::WebContentsObserver {
 public:
  FirstWebContentsProfiler(content::WebContents* web_contents,
                           startup_metric_utils::WebContentsWorkload workload);

 private:
  // Reasons for which profiling is deemed complete. Logged in UMA (do not re-
  // order or re-assign).
  enum FinishReason {
    // All metrics were successfully gathered.
    DONE = 0,
    // Abandon if blocking UI was shown during startup.
    ABANDON_BLOCKING_UI = 1,
    // Abandon if the content is hidden (lowers scheduling priority).
    ABANDON_CONTENT_HIDDEN = 2,
    // Abandon if the content is destroyed.
    ABANDON_CONTENT_DESTROYED = 3,
    // Abandon if the WebContents navigates away from its initial page.
    ABANDON_NEW_NAVIGATION = 4,
    // Abandon if the WebContents fails to load (e.g. network error, etc.).
    ABANDON_NAVIGATION_ERROR = 5,
    ENUM_MAX
  };

  ~FirstWebContentsProfiler() override = default;

  // content::WebContentsObserver:
  void DidFirstVisuallyNonEmptyPaint() override;
  void DocumentOnLoadCompletedInMainFrame() override;
  void DidStartNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;
  void WasHidden() override;
  void WebContentsDestroyed() override;

  // Whether this instance has finished collecting first-paint and main-frame-
  // load metrics (navigation metrics are recorded on a best effort but don't
  // prevent the FirstWebContentsProfiler from calling it).
  bool IsFinishedCollectingMetrics();

  // Logs |finish_reason| to UMA and deletes this FirstWebContentsProfiler.
  void FinishedCollectingMetrics(FinishReason finish_reason);

  // Whether an attempt was made to collect the "NonEmptyPaint" metric.
  bool collected_paint_metric_;

  // Whether an attempt was made to collect the "MainFrameLoad" metric.
  bool collected_load_metric_;

  // Whether an attempt was made to collect the "MainNavigationStart" metric.
  bool collected_main_navigation_start_metric_;

  // Whether an attempt was made to collect the "MainNavigationFinished" metric.
  bool collected_main_navigation_finished_metric_;

  const startup_metric_utils::WebContentsWorkload workload_;

  DISALLOW_COPY_AND_ASSIGN(FirstWebContentsProfiler);
};

FirstWebContentsProfiler::FirstWebContentsProfiler(
    content::WebContents* web_contents,
    startup_metric_utils::WebContentsWorkload workload)
    : content::WebContentsObserver(web_contents),
      collected_paint_metric_(false),
      collected_load_metric_(false),
      collected_main_navigation_start_metric_(false),
      collected_main_navigation_finished_metric_(false),
      workload_(workload) {}

void FirstWebContentsProfiler::DidFirstVisuallyNonEmptyPaint() {
  if (collected_paint_metric_)
    return;
  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
    FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
    return;
  }

  collected_paint_metric_ = true;
  startup_metric_utils::RecordFirstWebContentsNonEmptyPaint(
      base::TimeTicks::Now(), web_contents()
                                  ->GetMainFrame()
                                  ->GetProcess()
                                  ->GetInitTimeForNavigationMetrics());

  if (IsFinishedCollectingMetrics())
    FinishedCollectingMetrics(FinishReason::DONE);
}

void FirstWebContentsProfiler::DocumentOnLoadCompletedInMainFrame() {
  if (collected_load_metric_)
    return;
  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
    FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
    return;
  }

  collected_load_metric_ = true;
  startup_metric_utils::RecordFirstWebContentsMainFrameLoad(
      base::TimeTicks::Now());

  if (IsFinishedCollectingMetrics())
    FinishedCollectingMetrics(FinishReason::DONE);
}

void FirstWebContentsProfiler::DidStartNavigation(
    content::NavigationHandle* navigation_handle) {
  if (collected_main_navigation_start_metric_)
    return;
  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
    FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
    return;
  }

  if (content::IsBrowserSideNavigationEnabled()) {
    // With PlzNavigate, DidStartNavigation is called synchronously on
    // browser-initiated loads instead of through an IPC. This means that we
    // will miss this signal. Instead we record it when the commit completes.
    return;
  }

  // The first navigation has to be the main frame's.
  DCHECK(navigation_handle->IsInMainFrame());

  collected_main_navigation_start_metric_ = true;
  startup_metric_utils::RecordFirstWebContentsMainNavigationStart(
      base::TimeTicks::Now(), workload_);
}

void FirstWebContentsProfiler::DidFinishNavigation(
    content::NavigationHandle* navigation_handle) {
  if (collected_main_navigation_finished_metric_) {
    // Abandon profiling on a top-level navigation to a different page as it:
    //   (1) is no longer a fair timing; and
    //   (2) can cause http://crbug.com/525209 where one of the timing
    //       heuristics (e.g. first paint) didn't fire for the initial content
    //       but fires after a lot of idle time when the user finally navigates
    //       to another page that does trigger it.
    if (navigation_handle->IsInMainFrame() &&
        navigation_handle->HasCommitted() &&
        !navigation_handle->IsSameDocument()) {
      FinishedCollectingMetrics(FinishReason::ABANDON_NEW_NAVIGATION);
    }
    return;
  }

  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
    FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
    return;
  }

  // The first navigation has to be the main frame's.
  DCHECK(navigation_handle->IsInMainFrame());

  if (!navigation_handle->HasCommitted() ||
      navigation_handle->IsErrorPage()) {
    FinishedCollectingMetrics(FinishReason::ABANDON_NAVIGATION_ERROR);
    return;
  }

  if (content::IsBrowserSideNavigationEnabled()) {
    startup_metric_utils::RecordFirstWebContentsMainNavigationStart(
        navigation_handle->NavigationStart(), workload_);
    collected_main_navigation_start_metric_ = true;
  }

  collected_main_navigation_finished_metric_ = true;
  startup_metric_utils::RecordFirstWebContentsMainNavigationFinished(
      base::TimeTicks::Now());
}

void FirstWebContentsProfiler::WasHidden() {
  // Stop profiling if the content gets hidden as its load may be deprioritized
  // and timing it becomes meaningless.
  FinishedCollectingMetrics(FinishReason::ABANDON_CONTENT_HIDDEN);
}

void FirstWebContentsProfiler::WebContentsDestroyed() {
  FinishedCollectingMetrics(FinishReason::ABANDON_CONTENT_DESTROYED);
}

bool FirstWebContentsProfiler::IsFinishedCollectingMetrics() {
  return collected_paint_metric_ && collected_load_metric_;
}

void FirstWebContentsProfiler::FinishedCollectingMetrics(
    FinishReason finish_reason) {
  UMA_HISTOGRAM_ENUMERATION("Startup.FirstWebContents.FinishReason",
                            finish_reason, FinishReason::ENUM_MAX);
  if (!collected_paint_metric_) {
    UMA_HISTOGRAM_ENUMERATION("Startup.FirstWebContents.FinishReason_NoPaint",
                              finish_reason, FinishReason::ENUM_MAX);
  }
  if (!collected_load_metric_) {
    UMA_HISTOGRAM_ENUMERATION("Startup.FirstWebContents.FinishReason_NoLoad",
                              finish_reason, FinishReason::ENUM_MAX);
  }

  delete this;
}

}  // namespace

namespace metrics {

void BeginFirstWebContentsProfiling() {
  using startup_metric_utils::WebContentsWorkload;

  const BrowserList* browser_list = BrowserList::GetInstance();

  const auto first_browser = browser_list->begin();
  if (first_browser == browser_list->end())
    return;

  const TabStripModel* tab_strip = (*first_browser)->tab_strip_model();
  DCHECK(!tab_strip->empty());

  content::WebContents* web_contents = tab_strip->GetActiveWebContents();
  DCHECK(web_contents);

  const bool single_tab = browser_list->size() == 1 && tab_strip->count() == 1;

  // FirstWebContentsProfiler owns itself and is also bound to
  // |web_contents|'s lifetime by observing WebContentsDestroyed().
  new FirstWebContentsProfiler(web_contents,
                               single_tab ? WebContentsWorkload::SINGLE_TAB
                                          : WebContentsWorkload::MULTI_TABS);
}

}  // namespace metrics
