using Bit.Core.AdminConsole.Entities;
using Bit.Core.Auth.Entities;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models.Data;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Vault.Models.Data;
namespace Bit.Core.Auth.Services;
public interface IEmergencyAccessService
{
///
/// Invites a user via email to become an emergency contact for the Grantor user. The Grantor must have a premium subscription.
/// the grantor user must not be a member of the organization that uses KeyConnector.
///
/// The user initiating the emergency contact request
/// Emergency contact
/// Type of emergency access allowed to the emergency contact
/// The amount of time to pass before the invite is auto confirmed
/// a new Emergency Access object
Task InviteAsync(User grantorUser, string emergencyContactEmail, EmergencyAccessType accessType, int waitTime);
///
/// Sends an invite to the emergency contact associated with the emergency access id.
///
/// The grantor. This must be the owner of the Emergency Access object
/// The Id of the emergency access being requested.
/// void
Task ResendInviteAsync(User grantorUser, Guid emergencyAccessId);
///
/// A grantee user accepts the emergency contact request. This updates the emergency access status to be
/// "Accepted", this is the middle step before the grantor user confirms the request.
///
/// Id of the emergency access object being acted on.
/// User being invited to be an emergency contact
/// the tokenable that was sent via email
/// service dependency
/// void
Task AcceptUserAsync(Guid emergencyAccessId, User granteeUser, string token, IUserService userService);
///
/// The creator of the emergency access request can delete the request.
///
/// Id of the emergency access being acted on
/// Id of the owner trying to delete the emergency access request
/// void
Task DeleteAsync(Guid emergencyAccessId, Guid grantorId);
///
/// The grantor user confirms the acceptance of the emergency contact request. This stores the encrypted key allowing the grantee
/// access based on the emergency access type.
///
/// Id of the emergency access being acted on.
/// The grantor user key encrypted by the grantee public key; grantee.PubicKey(grantor.User.Key)
/// Id of grantor user
/// emergency access object associated with the Id passed in
Task ConfirmUserAsync(Guid emergencyAccessId, string key, Guid grantorId);
///
/// Fetches an emergency access object. The grantor user must own the object being fetched.
///
/// Id of emergency access object
/// Id of the owner of the emergency access object.
/// Details of the emergency access object
Task GetAsync(Guid emergencyAccessId, Guid grantorId);
///
/// Updates the emergency access object.
///
/// emergency access entity being updated
/// grantor user
/// void
Task SaveAsync(EmergencyAccess emergencyAccess, User grantorUser);
///
/// Initiates the recovery process. For either Takeover or view. Will send an email to the Grantor User notifying of the initiation.
///
/// EmergencyAccess Id
/// grantee user
/// void
Task InitiateAsync(Guid emergencyAccessId, User granteeUser);
///
/// Approves a recovery request. Sets the EmergencyAccess.Status to RecoveryApproved.
///
/// emergency access id
/// grantor user
/// void
Task ApproveAsync(Guid emergencyAccessId, User grantorUser);
///
/// Rejects a recovery request. Sets the EmergencyAccess.Status to Confirmed. This does not remove the emergency access entity. The
/// Grantee user can still initiate another recovery request.
///
/// emergency access id
/// grantor user
/// void
Task RejectAsync(Guid emergencyAccessId, User grantorUser);
///
/// This request is made by the Grantee user to fetch the policies for the Grantor User.
/// The Grantor User has to be the owner of the organization.
/// If the Grantor user has OrganizationUserType.Owner then the policies for the _Grantor_ user
/// are returned. This is used to ensure the password is of the proper complexity for the organization.
///
/// EmergencyAccess.Id being acted on
/// User making the request, this is the Grantee
/// null if the GrantorUser is not an organization owner; A list of policies otherwise.
Task> GetPoliciesAsync(Guid emergencyAccessId, User granteeUser);
///
/// Fetches the emergency access entity and grantor user. The grantor user is returned so the correct KDF configuration is
/// used for the new password.
///
/// Id of entity being accessed
/// grantee user of the emergency access entity
/// emergency access entity and the grantorUser
Task<(EmergencyAccess, User)> TakeoverAsync(Guid emergencyAccessId, User granteeUser);
///
/// Updates the grantor's password hash and updates the key for the EmergencyAccess entity.
///
/// Emergency Access Id being acted on
/// user making the request
/// new password hash set by grantee user
/// new encrypted user key
/// void
Task PasswordAsync(Guid emergencyAccessId, User granteeUser, string newMasterPasswordHash, string key);
///
/// sends a reminder email that there is a pending request for recovery.
///
/// void
Task SendNotificationsAsync();
///
/// This handles the auto approval of recovery requests started in the method.
/// An email will be sent to the Grantee and the Grantor notifying each the recovery has been approved.
///
/// void
Task HandleTimedOutRequestsAsync();
///
/// Fetched ciphers from the grantors account for the grantee to view.
///
/// Emergency access entity being acted on
/// user requesting cipher items
/// ciphers associated with the emergency access request
Task ViewAsync(Guid emergencyAccessId, User granteeUser);
///
/// Returns attachment if the grantee user has access to the cipher through the emergency access entity.
///
/// EmergencyAccess entity being acted on
/// cipher entity containing the attachment
/// Attachment entity
/// user making the request
/// attachment response
Task GetAttachmentDownloadAsync(Guid emergencyAccessId, Guid cipherId, string attachmentId, User granteeUser);
}