chromium/ios/chrome/browser/bookmarks/ui_bundled/bookmark_utils_ios.h

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

#ifndef IOS_CHROME_BROWSER_BOOKMARKS_UI_BUNDLED_BOOKMARK_UTILS_IOS_H_
#define IOS_CHROME_BROWSER_BOOKMARKS_UI_BUNDLED_BOOKMARK_UTILS_IOS_H_

#import <UIKit/UIKit.h>

#import <memory>
#import <set>
#import <string>
#import <vector>

#import "base/location.h"
#import "base/memory/raw_ptr.h"
#import "base/memory/weak_ptr.h"
#import "base/time/time.h"
#import "base/uuid.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios_forward.h"

class AuthenticationService;
enum class BookmarkStorageType;
class GURL;
@class MDCSnackbarMessage;

namespace bookmarks {
class BookmarkModel;
class BookmarkNode;
}  // namespace bookmarks

namespace syncer {
class SyncService;
}  // namespace syncer

namespace bookmark_utils_ios {

typedef std::vector<const bookmarks::BookmarkNode*> NodeVector;
typedef std::set<const bookmarks::BookmarkNode*> NodeSet;

// Finds bookmark node passed in `id`, in the `model`. Returns null if the
// node is found but not a folder.
const bookmarks::BookmarkNode* FindFolderById(
    const bookmarks::BookmarkModel* model,
    int64_t id);

// The iOS code is doing some munging of the bookmark folder names in order
// to display a slighly different wording for the default folders.
NSString* TitleForBookmarkNode(const bookmarks::BookmarkNode* node);

// Returns the storage type for a node, based on where `bookmark_node` exists
// in `bookmark_model`, i.e. under which permanent folder it exists.
// `bookmark_node` is the bookmark to query. It must not be null.
// `bookmark_model` is bookmark model. It must not be null. `bookmark_model`
// must contain `bookmark_node`. This function is linear in time in the depth of
// the bookmark_node.
BookmarkStorageType GetBookmarkStorageType(
    const bookmarks::BookmarkNode* bookmark_node,
    const bookmarks::BookmarkModel* bookmark_model);

// Returns true if the user is signed in and they opted in for the account
// bookmark storage.
bool IsAccountBookmarkStorageOptedIn(syncer::SyncService* sync_service);

// Returns true if the user opted-in and can use the account storage.
// E.g. if the passphrase is missing, the storage may not be available.
// `model` must not be null.
bool IsAccountBookmarkStorageAvailable(const bookmarks::BookmarkModel* model);

// Updates `node`.
// `folder` is the intended parent of `node`.
// Returns a boolean signifying whether any change was performed.
bool UpdateBookmark(const bookmarks::BookmarkNode* node,
                    NSString* title,
                    const GURL& url,
                    const bookmarks::BookmarkNode* folder,
                    bookmarks::BookmarkModel* model);

// Similar to `UpdateBookmark`, but returns a snackbar that allows to
// undo the performed action. Returns nil if there's nothing to undo.
// TODO(crbug.com/40137712): Refactor to include position and replace two
// functions below.
MDCSnackbarMessage* UpdateBookmarkWithUndoToast(
    const bookmarks::BookmarkNode* node,
    NSString* title,
    const GURL& url,
    const bookmarks::BookmarkNode* original_folder,
    const bookmarks::BookmarkNode* folder,
    bookmarks::BookmarkModel* model,
    ChromeBrowserState* browser_state,
    base::WeakPtr<AuthenticationService> authenticationService,
    raw_ptr<syncer::SyncService> syncService);

// Creates a new bookmark with `title`, `url`, at `position` under parent
// `folder`. Returns a snackbar with an undo action. Returns nil if operation
// failed or there's nothing to undo.
MDCSnackbarMessage* CreateBookmarkAtPositionWithUndoToast(
    NSString* title,
    const GURL& url,
    const bookmarks::BookmarkNode* folder,
    int position,
    bookmarks::BookmarkModel* model,
    ChromeBrowserState* browser_state);

// Updates a bookmark node position, and returns a snackbar with an undo action.
// Returns nil if the operation wasn't successful or there's nothing to undo.
MDCSnackbarMessage* UpdateBookmarkPositionWithUndoToast(
    const bookmarks::BookmarkNode* node,
    const bookmarks::BookmarkNode* folder,
    size_t position,
    bookmarks::BookmarkModel* model,
    ChromeBrowserState* browser_state);

// Deletes all nodes in `bookmarks` from `bookmark_model` and returns a snackbar
// with an undo action. Returns nil if the operation wasn't successful or
// there's nothing to undo.
MDCSnackbarMessage* DeleteBookmarksWithUndoToast(
    const std::set<const bookmarks::BookmarkNode*>& bookmarks,
    bookmarks::BookmarkModel* bookmark_model,
    ChromeBrowserState* browser_state,
    const base::Location& location);

// Deletes all nodes in `bookmarks`.
void DeleteBookmarks(const std::set<const bookmarks::BookmarkNode*>& bookmarks,
                     bookmarks::BookmarkModel* bookmark_model,
                     const base::Location& location);

// Move all `bookmarks_to_move` to the given `folder`, and returns a snackbar
// with an undo action. Returns nil if the operation wasn't successful or
// there's nothing to undo.
MDCSnackbarMessage* MoveBookmarksWithUndoToast(
    const std::vector<const bookmarks::BookmarkNode*>& bookmarks_to_move,
    bookmarks::BookmarkModel* model,
    const bookmarks::BookmarkNode* destination_folder,
    ChromeBrowserState* browser_state,
    base::WeakPtr<AuthenticationService> authenticationService,
    raw_ptr<syncer::SyncService> syncService);

// Move all `bookmarks` to the given `folder`.
// Returns whether this method actually moved bookmarks (for example, only
// moving a folder to its parent will return `false`).
bool MoveBookmarks(
    const std::vector<const bookmarks::BookmarkNode*>& bookmarks_to_move,
    bookmarks::BookmarkModel* model,
    const bookmarks::BookmarkNode* destination_folder);

// Category name for all bookmarks related snackbars.
extern NSString* const kBookmarksSnackbarCategory;

// Sorts a vector full of folders by title.
void SortFolders(NodeVector* vector);

// Returns a vector of top-level permanent folders as filtered by `type` and
// all their descendant folders, except for those included in `obstructions`
// which are excluded, as well as their descendants. The returned list is
// sorted depth-first, then alphabetically.
NodeVector VisibleNonDescendantNodes(const NodeSet& obstructions,
                                     const bookmarks::BookmarkModel* model,
                                     BookmarkStorageType type);

// Whether `vector1` contains only elements of `vector2` in the same order.
BOOL IsSubvectorOfNodes(const NodeVector& vector1, const NodeVector& vector2);

// Returns the indices in `vector2` of the items in `vector2` that are not
// present in `vector1`.
// `vector1` MUST be a subvector of `vector2` in the sense of `IsSubvector`.
std::vector<NodeVector::size_type> MissingNodesIndices(
    const NodeVector& vector1,
    const NodeVector& vector2);

// Creates bookmark path for `folderId` passed in. For eg: for folderId = 76,
// MobileBookmarks (3) --> Test1(76) will be returned as [3, 76], where the
// first element always represents a permanent folder. Returns nullptr if the
// folder is not found or is the root node.
NSArray<NSNumber*>* CreateBookmarkPath(const bookmarks::BookmarkModel* model,
                                       int64_t folder_id);

// Converts NSString entered by the user to a GURL.
GURL ConvertUserDataToGURL(NSString* urlString);

// The localized strings for adding bookmarks.
// `folder`:  The folder into which bookmarks were added. Must not be nil.
// `model` must not be null.
// `chosenByUser`: whether this is the last folder in which the user moved a
// bookmark since last time the set of model changed.
// `showCount`: Display the number of moved bookmarks in the snackbar.
// `count`: the number of bookmarks.
NSString* messageForAddingBookmarksInFolder(
    const bookmarks::BookmarkNode* folder,
    const bookmarks::BookmarkModel* model,
    bool chosenByUser,
    bool showCount,
    int count,
    base::WeakPtr<AuthenticationService> authenticationService,
    raw_ptr<syncer::SyncService> syncService);

// The bookmark is saved in the account if either following condition is true:
// * the saved folder is an account bookmark,
// * the sync consent has been granted and the bookmark data type is enabled
bool bookmarkSavedIntoAccount(
    BookmarkStorageType bookmarkStorageType,
    base::WeakPtr<AuthenticationService> authenticationService,
    raw_ptr<syncer::SyncService> syncService);

}  // namespace bookmark_utils_ios

#endif  // IOS_CHROME_BROWSER_BOOKMARKS_UI_BUNDLED_BOOKMARK_UTILS_IOS_H_