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

module data_sharing.mojom;

import "components/data_sharing/public/protocol/group_data.mojom";
import "mojo/public/mojom/base/absl_status.mojom";
import "url/mojom/url.mojom";

// Group action user received from Data Sharing SDK.
// Map to a subset of LoggingIntent enum in data_sharing_sdk_types.ts
enum GroupAction {
  kUnknown = 0,
  kJoinGroup = 1,
  kDeleteGroup = 2,
  kLeaveGroup = 3,
  kKeepGroup = 4,
  kStopSharing = 5,
};

// Group action progress received from Data Sharing SDK.
// Map to Progress enum in data_sharing_sdk_types.ts
enum GroupActionProgress {
  kUnknown = 0,
  kStarted = 1,
  kFailed = 2,
  kSuccess = 3,
};

struct ReadGroupsParams {
  array<ReadGroupParams> params;
};

struct ReadGroupParams {
  // Identifier of the people group.
  string group_id;

  // As an optimization, sending a consistency token will allow for reading
  // groups with bounded staleness. Without a consistency token, we'll always
  // read the most current group.
  string consistency_token;
};

// Result of the ReadGroups API.
struct ReadGroupsResult {
  // Returns GroupData array when ReadGroups is successful, otherwise
  // returns empty array.
  array<GroupData> groups;

  // Status code equivalent to absl::StatusCode. Returns 0 if successful.
  int32 status_code;
};

struct ReadGroupWithTokenParam {
  string group_id;
  string access_token;
};

struct ReadGroupWithTokenResult {
  // Return GroupData if successful.
  GroupData? group;

  // Status code equivalent to absl::StatusCode. Returns 0 if successful.
  int32 status_code;
};

struct SharedTab {
  // Url of the tab, trimmed to domain e.g. google.com. This is for
  // display only and will not be consumed as a URL. Use bare string here
  // because the Typescript on the other side cannot format the url to domain
  // only like how it's done in C++ and the domain is all we need.
  string display_url;

  // Url of the tab favicon.
  url.mojom.Url favicon_url;
};

// Preview data of the shared tab group. Shown in the Join dialog.
struct GroupPreview {
  // Group title.
  string title;

  // Tabs in the group.
  array<SharedTab> shared_tabs;

  // Status code equivalent to absl::StatusCode. Returns 0 if successful.
  mojo_base.mojom.AbslStatusCode status_code;
};

// Factory ensures that the Page and PageHandler interfaces are always created
// together without requiring an initialization call from the WebUI to the
// handler.
interface PageHandlerFactory {
  // The WebUI calls this method when the page is first initialized.
  CreatePageHandler(
      pending_remote<Page> page, pending_receiver<PageHandler> handler);
};

// Browser-side handler for requests from WebUI page.
interface PageHandler {
  // Ask the browser to show the UI. Called when the page is loaded and ready to
  // show.
  ShowUI();

  // Ask the browser to close the UI and handle some special codes.
  CloseUI(int32 status_code);

  // Called when the api page is fully initialized and authenticated.
  // All other APIs on the Page such as ReadGroups should only be invoked
  // after ApiInitComplete.
  ApiInitComplete();

  // Make the tab group shared and get the shared link.
  // Used only in first time copy link button is clicked on Shared flow.
  // This call may fail due to connectivity problems.
  // Return nullopt if it fails.
  // After this call is successful, all subsequent calls will go through
  // GetShareLink instead.
  MakeTabGroupShared(string tab_group_id, string group_id, string access_token)
      => (url.mojom.Url? url);

  // `group_id` connects the shared tab group with people group. `access_token`
  // is used to check link validity. Chrome stitches them together with a host
  // and generates an invite link. Owner can share the link to the public.
  // This call should be always successful.
  GetShareLink(string group_id, string access_token) => (url.mojom.Url url);

  // Ask the browser for the group preview.
  GetTabGroupPreview(string group_id, string access_token)
      => (GroupPreview group_preview);

  // Ask Chrome to open the tab group in current browser once the "Join and
  // Open" is pressed from the Join dialog.
  OpenTabGroup(string group_id);

  // Call before stop sharing.
  AboutToUnShareTabGroup(string tab_group_id);

  // Call after stop sharing succeeded.
  OnTabGroupUnShareComplete(string tab_group_id);

  // Call when group action is called.
  OnGroupAction(GroupAction action, GroupActionProgress progress);
};

// WebUI-side handler for requests from the browser.
interface Page {
  // Called when the access token of the primary account is fetched.
  // The token is used by data sharing SDK to authenticate the current user.
  OnAccessTokenFetched(string access_token);

  // Read groups given a list of ReadGroupParams.
  ReadGroups(ReadGroupsParams read_groups_params) => (ReadGroupsResult result);

  // Read a single group given group_id and access_token.
  ReadGroupWithToken(ReadGroupWithTokenParam param)
      => (ReadGroupWithTokenResult result);

  // Delete the group given group_id.
  // Return status code equivalent to absl::StatusCode.
  DeleteGroup(string group_id) => (int32 status_code);

  // Leave the group given group_id.
  // Return status code equivalent to absl::StatusCode.
  LeaveGroup(string group_id) => (int32 status_code);
};
