// 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.

#ifndef IOS_WEB_NAVIGATION_WK_BASED_NAVIGATION_MANAGER_IMPL_H_
#define IOS_WEB_NAVIGATION_WK_BASED_NAVIGATION_MANAGER_IMPL_H_

#include <stddef.h>

#include <memory>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#import "ios/web/navigation/navigation_item_impl.h"
#import "ios/web/navigation/navigation_manager_impl.h"
#include "ios/web/navigation/time_smoother.h"
#include "ios/web/public/reload_type.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"

@class WKBackForwardListItem;

namespace base {
class ElapsedTimer;
}

namespace web {
class BrowserState;
class NavigationItem;
struct Referrer;
class SessionStorageBuilder;

// Name of UMA histogram to log the time spent on asynchronous session
// restoration.
extern const char kRestoreNavigationTime[];

// WKBackForwardList based implementation of NavigationManagerImpl.
// This class relies on the following WKWebView APIs, defined by the
// CRWWebViewNavigationProxy protocol:
//   @property URL
//   @property backForwardList
//   - goToBackForwardListItem:
//
// This navigation manager uses WKBackForwardList as the ground truth for back-
// forward navigation history. It uses the Associated Objects runtime feature
// to link a NavigationItemImpl object to each WKBackForwardListItem to store
// additional states needed by the embedder.
//
// For all main frame navigations (both UI-initiated and renderer-initiated),
// the NavigationItemImpl objects are created proactively via AddPendingItem and
// CommitPendingItem.
//
// Non-main-frame navigations can only be initiated from the renderer. The
// NavigationItemImpl objects in this case are created lazily in GetItemAtIndex
// because the provisional load and commit events for iframe navigation are not
// visible via the WKNavigationDelegate interface. Consequently, pending item
// and previous item are only tracked for the main frame.
//
// Empty Window Open Navigation edge case:
//
//   If window.open() is called with an empty URL, WKWebView does not seem to
//   create a WKBackForwardListItem for the first about:blank navigation. Any
//   subsequent navigation in this window will replace the about:blank entry.
//   This is consistent with the HTML spec regarding Location-object navigation
//   when the browser context's only Document is about:blank:
//   https://html.spec.whatwg.org/multipage/history.html (Section 7.7.4)
//
//   This navigation manager will still create a pendingNavigationItem for this
//   "empty window open item" and allow CommitPendingItem() to be called on it.
//   All accessors will behave identically as if the navigation history has a
//   single normal entry. The only difference is that a subsequent call to
//   CommitPendingItem() will *replace* the empty window open item. From this
//   point onward, it is as if the empty window open item never occurred.
//
// Detach from web view edge case:
//
//   As long as this navigation manager is alive, the navigation manager
//   delegate should not delete its WKWebView. However, legacy use cases exist
//   (e.g. https://crbug/770914). As a workaround, before deleting the
//   WKWebView, the delegate must call
//   NavigationManagerImpl::DetachFromWebView() to cache the current session
//   history. This puts the navigation manager in a detached state. While in
//   this state, all getters are serviced using the cached session history.
//   Mutation methods are not allowed. The navigation manager returns to the
//   attached state when a new navigation starts.
class WKBasedNavigationManagerImpl : public NavigationManagerImpl {
 public:
  WKBasedNavigationManagerImpl();
  ~WKBasedNavigationManagerImpl() override;

  // NavigationManagerImpl:
  void SetSessionController(CRWSessionController* session_controller) override;
  void InitializeSession() override;
  void OnNavigationItemsPruned(size_t pruned_item_count) override;
  void OnNavigationItemChanged() override;
  void OnNavigationItemCommitted() override;
  void DetachFromWebView() override;
  CRWSessionController* GetSessionController() const override;
  void AddTransientItem(const GURL& url) override;
  void AddPendingItem(
      const GURL& url,
      const web::Referrer& referrer,
      ui::PageTransition navigation_type,
      NavigationInitiationType initiation_type,
      UserAgentOverrideOption user_agent_override_option) override;
  void CommitPendingItem() override;
  int GetIndexForOffset(int offset) const override;
  // Returns the previous navigation item in the main frame.
  int GetPreviousItemIndex() const override;
  void SetPreviousItemIndex(int previous_item_index) override;
  void AddPushStateItemIfNecessary(const GURL& url,
                                   NSString* state_object,
                                   ui::PageTransition transition) override;
  bool IsRestoreSessionInProgress() const override;

  // NavigationManager:
  BrowserState* GetBrowserState() const override;
  WebState* GetWebState() const override;
  NavigationItem* GetVisibleItem() const override;
  void DiscardNonCommittedItems() override;
  int GetItemCount() const override;
  NavigationItem* GetItemAtIndex(size_t index) const override;
  int GetIndexOfItem(const NavigationItem* item) const override;
  int GetPendingItemIndex() const override;
  bool RemoveItemAtIndex(int index) override;
  bool CanGoBack() const override;
  bool CanGoForward() const override;
  bool CanGoToOffset(int offset) const override;
  void GoBack() override;
  void GoForward() override;
  NavigationItemList GetBackwardItems() const override;
  NavigationItemList GetForwardItems() const override;
  void CopyStateFromAndPrune(const NavigationManager* source) override;
  bool CanPruneAllButLastCommittedItem() const override;
  void Restore(int last_committed_item_index,
               std::vector<std::unique_ptr<NavigationItem>> items) override;
  void AddRestoreCompletionCallback(base::OnceClosure callback) override;
  void LoadIfNecessary() override;

 private:
  // The SessionStorageBuilder functions require access to private variables of
  // NavigationManagerImpl.
  friend SessionStorageBuilder;

  // Access shim for NavigationItems associated with the WKBackForwardList. It
  // is responsible for caching NavigationItems when the navigation manager
  // detaches from its web view.
  class WKWebViewCache {
   public:
    explicit WKWebViewCache(WKBasedNavigationManagerImpl* navigation_manager);
    ~WKWebViewCache();

    // Returns true if the navigation manager is attached to a WKWebView.
    bool IsAttachedToWebView() const;

    // Caches NavigationItems from the WKWebView in |this| and changes state to
    // detached.
    void DetachFromWebView();

    // Clears the cached NavigationItems and resets state to attached. Callers
    // that wish to restore the cached navigation items into the new web view
    // must call ReleaseCachedItems() first.
    void ResetToAttached();

    // Returns ownership of the cached NavigationItems. This is convenient for
    // restoring session history when reattaching to a new web view.
    std::vector<std::unique_ptr<NavigationItem>> ReleaseCachedItems();

    // Returns the number of items in the back-forward history.
    size_t GetBackForwardListItemCount() const;

    // Returns the absolute index of WKBackForwardList's |currentItem| or -1 if
    // |currentItem| is nil. If navigation manager is in detached mode, returns
    // the cached value of this property captured at the last call of
    // DetachFromWebView().
    int GetCurrentItemIndex() const;

    // Returns the NavigationItem associated with the WKBackForwardListItem at
    // |index|. If |create_if_missing| is true and the WKBackForwardListItem
    // does not have an associated NavigationItem, creates a new one and returns
    // it to the caller.
    NavigationItemImpl* GetNavigationItemImplAtIndex(
        size_t index,
        bool create_if_missing) const;

    // Returns the WKBackForwardListItem at |index|. Must only be called when
    // IsAttachedToWebView() is true.
    WKBackForwardListItem* GetWKItemAtIndex(size_t index) const;

   private:
    WKBasedNavigationManagerImpl* navigation_manager_;
    bool attached_to_web_view_;

    std::vector<std::unique_ptr<NavigationItemImpl>> cached_items_;
    int cached_current_item_index_;

    DISALLOW_COPY_AND_ASSIGN(WKWebViewCache);
  };

  // NavigationManagerImpl:
  NavigationItemImpl* GetNavigationItemImplAtIndex(size_t index) const override;
  NavigationItemImpl* GetLastCommittedItemInCurrentOrRestoredSession()
      const override;
  int GetLastCommittedItemIndexInCurrentOrRestoredSession() const override;
  // Returns the pending navigation item in the main frame. Unlike
  // GetPendingItem(), this method does not return null during session
  // restoration (and returns last known pending item instead).
  NavigationItemImpl* GetPendingItemInCurrentOrRestoredSession() const override;
  NavigationItemImpl* GetTransientItemImpl() const override;
  void FinishGoToIndex(int index,
                       NavigationInitiationType initiation_type,
                       bool has_user_gesture) override;
  void FinishReload() override;
  void FinishLoadURLWithParams() override;
  bool IsPlaceholderUrl(const GURL& url) const override;

  // The pending main frame navigation item. This is nullptr if there is no
  // pending item or if the pending item is a back-forward navigation, in which
  // case the NavigationItemImpl is stored on the WKBackForwardListItem.
  std::unique_ptr<NavigationItemImpl> pending_item_;

  // -1 if pending_item_ represents a new navigation or there is no pending
  // navigation. Otherwise, this is the index of the pending_item in the
  // back-forward list.
  int pending_item_index_;

  // Index of the previous navigation item in the main frame. If there is none,
  // this field will have value -1.
  int previous_item_index_;

  // Index of the last committed item in the main frame. If there is none, this
  // field will equal to -1.
  int last_committed_item_index_;

  // The NavigationItem that corresponds to the empty window open navigation. It
  // has to be stored separately because it has no WKBackForwardListItem. It is
  // not null if when CommitPendingItem() is last called, the WKBackForwardList
  // is empty but not nil. Any subsequent call to CommitPendingItem() will reset
  // this field to null.
  std::unique_ptr<NavigationItemImpl> empty_window_open_item_;

  // The transient item in main frame.
  std::unique_ptr<NavigationItemImpl> transient_item_;

  // Time smoother for navigation item timestamps. See comment in
  // navigation_controller_impl.h.
  // NOTE: This is mutable because GetNavigationItemImplAtIndex() needs to call
  // TimeSmoother::GetSmoothedTime() with a const 'this'. Since NavigationItems
  // have to be lazily created on read, this is the only workaround.
  mutable TimeSmoother time_smoother_;

  WKWebViewCache web_view_cache_;

  // Whether this navigation manager is in the process of restoring session
  // history into WKWebView. It is set in Restore() and unset in the first
  // OnNavigationItemCommitted() callback.
  bool is_restore_session_in_progress_ = false;

  // Non null during the session restoration. Created when session restoration
  // is started and reset when the restoration is finished. Used to log UMA
  // histogram that measures session restoration time.
  std::unique_ptr<base::ElapsedTimer> restoration_timer_;

  // The active navigation entry in the restored session. GetVisibleItem()
  // returns this item when |is_restore_session_in_progress_| is true so that
  // clients of this navigation manager gets sane values for visible title and
  // URL.
  std::unique_ptr<NavigationItem> restored_visible_item_;

  // Non-empty only during the session restoration. The callbacks are
  // registered in AddRestoreCompletionCallback() and are executed in the first
  // OnNavigationItemCommitted() callback.
  std::vector<base::OnceClosure> restore_session_completion_callbacks_;

  DISALLOW_COPY_AND_ASSIGN(WKBasedNavigationManagerImpl);
};

}  // namespace web

#endif  // IOS_WEB_NAVIGATION_WK_BASED_NAVIGATION_MANAGER_IMPL_H_
