{-# LANGUAGE TemplateHaskell #-}

-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2025 Wire Swiss GmbH <opensource@wire.com>
--
-- This program is free software: you can redistribute it and/or modify it under
-- the terms of the GNU Affero General Public License as published by the Free
-- Software Foundation, either version 3 of the License, or (at your option) any
-- later version.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-- details.
--
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Wire.GalleyAPIAccess where

import Data.Currency qualified as Currency
import Data.Id
import Data.Json.Util (UTCTimeMillis)
import Data.LegalHold (UserLegalHoldStatus)
import Data.Qualified
import Data.Range
import Imports
import Network.Wai.Utilities.Error qualified as Wai
import Polysemy
import Wire.API.Conversation
import Wire.API.Routes.Internal.Brig.EJPD (EJPDConvInfo)
import Wire.API.Routes.Internal.Galley.TeamsIntra qualified as Team
import Wire.API.Team
import Wire.API.Team.Conversation qualified as Conv
import Wire.API.Team.Feature
import Wire.API.Team.LegalHold
import Wire.API.Team.Member qualified as Team
import Wire.API.Team.Member.Info qualified as Team
import Wire.API.Team.Role
import Wire.API.Team.SearchVisibility
import Wire.API.User.Client (UserClients)

data ShowOrHideInvitationUrl = ShowInvitationUrl | HideInvitationUrl
  deriving (Eq, Show)

data MLSOneToOneEstablished
  = Established
  | NotEstablished
  | NotAMember
  deriving (Eq, Show)

data GalleyAPIAccess m a where
  CreateSelfConv ::
    UserId ->
    GalleyAPIAccess m ()
  GetConv ::
    UserId ->
    Local ConvId ->
    GalleyAPIAccess m (Maybe (OwnConversation GroupConvType))
  GetTeamConv ::
    UserId ->
    TeamId ->
    ConvId ->
    GalleyAPIAccess m (Maybe Conv.TeamConversation)
  NewClient ::
    UserId ->
    ClientId ->
    GalleyAPIAccess m ()
  CheckUserCanJoinTeam ::
    TeamId ->
    GalleyAPIAccess m (Maybe Wai.Error)
  AddTeamMember ::
    UserId ->
    TeamId ->
    Maybe (UserId, UTCTimeMillis) ->
    Role ->
    GalleyAPIAccess m Bool
  CreateTeam ::
    UserId ->
    NewTeam ->
    TeamId ->
    GalleyAPIAccess m ()
  GetTeamMember ::
    UserId ->
    TeamId ->
    GalleyAPIAccess m (Maybe Team.TeamMember)
  GetTeamMembersWithLimit ::
    TeamId ->
    Maybe (Range 1 Team.HardTruncationLimit Int32) ->
    GalleyAPIAccess m Team.TeamMemberList
  SelectTeamMemberInfos ::
    TeamId ->
    [UserId] ->
    GalleyAPIAccess m Team.TeamMemberInfoList
  SelectTeamMembers ::
    TeamId ->
    [UserId] ->
    GalleyAPIAccess m [Team.TeamMember]
  GetTeamId ::
    UserId ->
    GalleyAPIAccess m (Maybe TeamId)
  GetTeam ::
    TeamId ->
    GalleyAPIAccess m Team.TeamData
  FindTeam ::
    TeamId ->
    GalleyAPIAccess m (Maybe Team.TeamData)
  GetTeamName ::
    TeamId ->
    GalleyAPIAccess m Team.TeamName
  GetTeamLegalHoldStatus ::
    TeamId ->
    GalleyAPIAccess m (LockableFeature LegalholdConfig)
  GetUserLegalholdStatus ::
    Local UserId -> TeamId -> GalleyAPIAccess m (Maybe UserLegalHoldStatusResponse)
  GetTeamSearchVisibility ::
    TeamId ->
    GalleyAPIAccess m TeamSearchVisibility
  ChangeTeamStatus ::
    TeamId ->
    Team.TeamStatus ->
    Maybe Currency.Alpha ->
    GalleyAPIAccess m ()
  FinalizeDeleteTeam ::
    Local UserId ->
    Maybe ConnId ->
    TeamId ->
    GalleyAPIAccess m ()
  MemberIsTeamOwner ::
    TeamId ->
    UserId ->
    GalleyAPIAccess m Bool
  GetAllTeamFeaturesForUser ::
    Maybe UserId ->
    GalleyAPIAccess m AllTeamFeatures
  GetFeatureConfigForTeam ::
    ( IsFeatureConfig feature,
      Typeable feature
    ) =>
    TeamId ->
    GalleyAPIAccess m (LockableFeature feature)
  GetVerificationCodeEnabled ::
    TeamId ->
    GalleyAPIAccess m Bool
  GetExposeInvitationURLsToTeamAdmin ::
    TeamId ->
    GalleyAPIAccess m ShowOrHideInvitationUrl
  IsMLSOne2OneEstablished ::
    Local UserId ->
    Qualified UserId ->
    GalleyAPIAccess m MLSOneToOneEstablished
  UnblockConversation ::
    Local UserId ->
    Maybe ConnId ->
    Qualified ConvId ->
    GalleyAPIAccess m (OwnConversation GroupConvType)
  GetEJPDConvInfo ::
    UserId ->
    GalleyAPIAccess m [EJPDConvInfo]
  GetTeamAdmins :: TeamId -> GalleyAPIAccess m Team.TeamMemberList
  InternalGetConversation :: ConvId -> GalleyAPIAccess m (Maybe (Conversation GroupConvType))
  GetTeamContacts ::
    UserId ->
    GalleyAPIAccess m (Maybe Team.TeamMemberList)
  GuardLegalHold :: LegalholdProtectee -> UserClients -> GalleyAPIAccess m ()
  GetUserLHStatus :: Maybe TeamId -> UserId -> GalleyAPIAccess m UserLegalHoldStatus
  GetUsersLHStatus :: [UserId] -> GalleyAPIAccess m [(UserId, UserLegalHoldStatus)]
  UpdateTeamMember ::
    UserId ->
    TeamId ->
    Role ->
    GalleyAPIAccess m ()
  IsEmailValidationEnabledTeam ::
    TeamId ->
    GalleyAPIAccess m Bool

makeSem ''GalleyAPIAccess
