/*
  Copyright (C) 2020, University of the Basque Country (UPV/EHU)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.mcopenplatform.muoapi;

import org.mcopenplatform.muoapi.IMCOPCallback;

/**
 * AIDL definition {@link https://developer.android.com/guide/components/aidl.html}
 * Used as a callback for MCOP SDK server-client communication, and for MCPTT (Mission Critical Push to Talk) Services.
 * @version 0.1
 */
interface IMCOPsdk {

    /**
     * Allows to synchronously get the capabilities from the different MCPTT SDK plugins.
     *
     * @return Returns an structure with all the capabilities.
     * @throws android.os.RemoteException
     */
    String getMCOPCapabilities();

    /**
     * @brief Set the client address
     *
     * This function set the address of the client. It must be call before the client login, otherwise an error will be returned.
     *
     * @param ip Indicates the address on IPv4 format.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_NET_PORT
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int selectInterface(String ip, in Map tag);

    /**
     * @brief Register the user
     *
     * This function starts the MCS system login procedure (SIP Registration + MCS authentication + MCS service authorization).
     *
     * In case of re-execution it restarts the login procedure, if already on it.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.RegistrationEventExtras for more information about asynchronous responses of this method.
     *
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int login();

    /**
     *
     * @brief Requests the IdMS for service authorization
     *
     * Once the authentication procedure has been carried out against the IDMS, this function must be called to continue with the login
     * process started with #login() function.
     *
     * Before making the call to this function, the client will receive an asynchronous {@link org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.registrationEvent } event which contains a *request uri* that
     * upper client layers must use to authenticate against the IDMS.
     *
     * The URL obtained as a result of IDMS authentication should be passed to the SDK so that it can verify the authentication and start with service authorization.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.RegistrationEventExtras for more information about asynchronous responses of this method.
     * @param url String with URL format, obtained as a result of the IDMS authentication process.
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int authorizeUser(String url);

    /**
     * @brief Unregister user
     *
     * This function starts the MCS system logout procedure.
     *
     * In case of re-execution it restarts the logout procedure, if already on it.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.RegistrationEventExtras for more information about asynchronous responses of this method.
     *
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int logout();

    /**
     * @brief Generates a unique id
     *
     * This function generates a unique id, to be used with #makeCall .
     *
     * @return Generated unique ID, if there are no errors. Otherwise, a #null object will be returned.
     * @throws android.os.RemoteException
     */
    String generateUniqueId();

    /**
     * @brief Make MCPTT/MCVIDEO calls
     *
     * Make a call to the requested SIP URI list. Those SIP URIs might be a private user MCPTT/MCVIDEO ID or a group ID.
     * The *callType* argument value indicates how this SIP URIs should be interpreted.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras for more information about asynchronous responses of this method.
     *
     * @param calledIds List of request SIP URIs. This list must only contain one SIP URI, except for First-To-Answer calls.
     * If the list contains more than one elements, the first one will be used.
     * If NULL, the default contact will be called.
     * @param callType  Integer that contains a series of FLAGs indicating the requested call type. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallTypeEnum} for all possible values.
     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_CALL_ANSWER_MODE_KEY
     *                 - #TAG_CALL_EMERG_ALERT_KEY
     *                 - #TAG_CALL_MIC_MUTE_KEY
     *                 - #TAG_CALL_SPEAKER_MUTE_KEY
     *                 - #TAG_CALL_IMPLICIT_REQUEST_KEY
     *                 - #TAG_CALL_IMPLICIT_GRANTED_KEY
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int makeCall(in String[] calledIds, int callType, String sessionID, in Map tags);

    /**
     * @brief Accept an incoming call
     *
     * Accept incoming call from individual user or group.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras for more information about asynchronous responses of this method.

     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_CALL_MIC_MUTE_KEY
     *                 - #TAG_CALL_SPEAKER_MUTE_KEY
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int acceptCall(String sessionID, in Map tags);

    /**
     * @brief Hang up a call
     *
     * Hang up an ongoing call or cancel a call that has not been established yet.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras for more information about asynchronous responses of this method.
     *
     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int hangUpCall(String sessionID);

    /**
     * @brief Change ongoing call state
     *
     * Change the state of an ongoing call (e.g change call priority level).
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras for more information about asynchronous responses of this method.

     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @param updateType New updated state of the session. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.EmergencyTypeEnum} for all possible values.
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int updateCallStatus(String sessionID, int updateType);

    /**
     * @brief Mute/Unmute the microphone
     *
     * This functions gives the possibility to mute the microphone for a specific call.
     *
     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @param mute Boolean indicating if the microphone is muted or not. True means mute.
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int setMute(String sessionID,boolean mute);

    /**
     * @brief Mute/Unmute the speaker
     *
     * This functions gives the possibility to mute the speaker for a specific call.
     *
     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @param mute Boolean indicating if the speaker is muted or not. True means mute.
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int setSpeakerMute(String sessionID,boolean mute);

    /**
     * @brief Perform an operation related to media control mechanisms
     *
     * Perform an operation related to floor control or transmission control mechanisms.
     * These mechanisms are MCPTT and MCVIDEO call's audio and video controlling mechanisms respectively.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.ControlMechanismEventExtras for more information about asynchronous responses of this method.
     *
     * @param sessionID Call session identifier that unequivocally identifies the call.
     * @param controlReqType Media control mechanism event type. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.ControlMechanismEventExtras.ControlMechanismOperationTypeEnum} for all possible values.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_CTRL_MECH_PRIO
     *                 - #TAG_CTRL_MECH_MCVIDEO_USER_ID
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int controlMechanismOperation(String sessionID, int controlReqType, in Map tags);

    /**
     * @brief Remote change of selected group
     *
     * Change the selected group (the group the other user is listening to) of another user.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras for more information about asynchronous responses of this method.
     * The user should be a member of the group. Otherwise, an error will be returned.
     *
     * @param userID The MCPTT ID or MCVIDEO ID of the target user
     * @param groupID The identifier of the group
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_GROUP_SERVICES
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int changeRemoteGroup(String userID, String groupID, in Map tags);

    /**
     * @brief Set the emergency alert state for a certain group
     *
     * Enable or disable the emergency alert state of a specific group, even if there is no call in that group
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras for more information about asynchronous responses of this method.
     *
     * @param groupID The identifier of the group
     * @param enable  Boolean indicating if the emergency alert shall be enabled or not. True means enable.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_EMERGENCY_ALERT_ORIGINATED_BY
     *                 - #TAG_GROUP_SERVICES
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int setGroupEmergencyAlertState(String groupID, boolean enable, in Map tags);

    /**
     * @brief Explicit configuration information retrieval
     *
     * Request the full configuration information of the user
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationInfoEventExtras for more information about asynchronous responses of this method.
     *
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int getConfigurationInfo();

    /**
     * @brief Explicit group information retrieval
     *
     * Request the information of all groups of which the user is a member
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras for more information about asynchronous responses of this method.
     *
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int getGroupsInfo();

    /**
     * @brief Explicit affiliation information retrieval
     *
     * Request the user affiliation status of all groups of which the user is a member.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras for more information about asynchronous responses of this method.
     *
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int getGroupsAffiliation();

    /**
     * @brief Perform an affiliation status change
     *
     * Perform an affiliation change on the affiliation status of the user
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras for more information about asynchronous responses of this method.
     *
     * @param groupID The identifier of the group
     * @param affiliationRequestType Affiliation request type. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.AffiliationRequestTypeEnum} for all possible values.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_AFFILIATION_REMOTE_USER_ID
     *                 - #TAG_AFFILIATION_SERVICES
     *                 - #TAG_AFFILIATION_REMOTE_NEGOTIATED_MODE
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int affiliationOperation(String groupID, int affiliationRequestType,in Map tags);

    /**
     * @brief Explicit functional alias status retrieval
     *
     * Get functional alias status (active, inactive...)
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.FunctionalAliasEventExtras for more information about asynchronous responses of this method.
     *
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int getFunctionalAliasStatus();

    /**
     * @brief Perform functional alias operation
     *
     * Perform functional alias state change operations, like activate or deactivate a specific alias.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.FunctionalAliasEventExtras for more information about asynchronous responses of this method.
     *
     * @param functionalAliasId Unequivocally identifies the functional alias on which the operation is to be performed. The functional alias list will be received in the event {@link ConstantsMCOP.ActionsCallBack#functionalAliasEvent}
     * @param functionalAliasRequestType Functional alias request type. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.FunctionalAliasEventExtras.FunctionalAliasOperationTypeEnum} for all possible values.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_FUNCTIONAL_ALIAS_TAKE_OVER
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int functionalAliasOperation(String functionalAliasId, int functionalAliasRequestType,in Map tags);

    /**
     * @brief Create SDS conversation
     *
     * Create a new MCDATA SDS conversation
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.MCDataEventExtras for more information about asynchronous responses of this method.
     *
     * @param recipientID MCDATA ID of the user or group with whom an SDS conversation will be created.
     * @param conversationType Conversation type. See {@link ConstantsMCOP.MCDataEventExtras.SdsNotificationTypeEnum} for all possible values.
     * @param defaultDispositionReqType Default disposition request type. Indicates which type of notification will be requested to recipients in response to a sent SDS message.
     *                                  See {@link org.mcopenplatform.muoapi.ConstantsMCOP.MCDataEventExtras.SdsNotificationTypeEnum} for all possible values.
     * @return Returns the UUID that unequivocally identifies the conversation if there are no errors. Otherwise, a #null structure will be returned.
     * @throws android.os.RemoteException
     */
    String createConversation(String recipientID, int conversationType, int defaultDispositionReqType);

    /**
     * @brief Send SDS message
     *
     * Send an SDS message within a specific conversation.
     * It can include several payloads and payload types.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.MCDataEventExtras for more information about asynchronous responses of this method.
     *
     * @param conversationID  the UUID that unequivocally identifies the conversation
     * @param payloads Array containing all the payloads to be sent. In the case of being a binary data it must be encoded in base64
     * @param payloadsType Array containing all the payload type of the #payloads to be sent. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.MCDataEventExtras.SdsPayloadTypeEnum} for all possible values.
     * @param dateTime  Calendar's time in milliseconds. {@link java.util.Calendar#getTimeInMillis()}.
     * @param inReplyToID  an UUID indicating the ID of the message which is being replied. Optional
     * @param notificationType Indicates the type of notification requested by the user. See {@link org.mcopenplatform.muoapi.ConstantsMCOP.MCDataEventExtras.SdsNotificationTypeEnum}for all possible values. Optional
     * @return Returns the UUID that unequivocally identifies the message if there are no errors. Otherwise, a #null structure will be returned.
     * @throws android.os.RemoteException
     */
    String sendSDS(String conversationID, in String[] payloads,in int[] payloadsType,long dateTime,String inReplyToID,int notificationType);

    /**
     * @brief Send a notification indicating that a SDS message has been read
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.MCDataEventExtras for more information about asynchronous responses of this method.
     * @param recipientID MCDATA ID of the user or group of the SDS conversation.
     * @param conversationID  the UUID that unequivocally identifies the conversation to which the SDS belongs.
     * @param messageID  the UUID that unequivocally identifies the message for which the notification will sent.
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int readNotificationSDS(String recipientID,String conversationID,String messageID);

    /**
     * @brief Retrieve SDS conversations history
     *
     * Retrieve SDS conversations history.
     * If #recipient_id and #conversationID are NULL, all stored conversation histories will be retrieved
     * If #recipient_id* contains the MCDATA ID of a specific user and #conversationID is NULL, the event generated in response to this function will only return the stored conversation history associated to that user.
     * If #recipient_id* contains the MCDATA ID of a specific user and #conversationID contains a conversation valid identifier, retrieves all stored SDS messages associated to a specific conversation.
     *
     * @param conversationID  the UUID that unequivocally identifies the conversation to which the SDS belongs.
     * @param recipientID MCDATA ID of the user or group of the SDS conversation.
     * @param tags List of optional tags. Possible values are:
     *                 - #TAG_SDS_FILTER_START_DATA
     *                 - #TAG_SDS_FILTER_END_DATA
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int getAllSDS(String conversationID,String recipientID,in Map tags);

    //#endif HAVE_MCDATA

    /**
     * @brief Manage groups (e. g create a new group)
     *
     * Allows performing different group management related operation such as group or temporary group formation, group removal or temporary group tear down.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras for more information about asynchronous responses of this method.
     *
     * @param groupID The identifier of the group
     * @param groupOperationType  Group management operation type. See {@link ConstantsMCOP.GroupInfoEventExtras.GroupOperationRequestTypeEnum} for all possible values.
     * @param tags List of optional tags. Possible values are all the fields defined for group information data
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int groupManagementOperation(String groupID, int groupOperationType, in Map tags);

    /**
     * @brief Manage user affiliation subscription
     *
     * Allows managing self and target user affiliation. Flag {@link ConstantsMCOP#MANUAL_AFFILIATION_SUBSCRIPTION_CONTROL} must be shared in binding time, otherwise the function will return an error.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras for more information about asynchronous responses of this method.
     *
     * @param userID The identifier of the user whose affiliation subscription will be managed
     * @param enable Indicates if the subscription should be enabled or disabled. True means enabled
     * @return 0 if there are no errors. Otherwise, a negative error code will be returned.
     * @throws android.os.RemoteException
     */
    int affiliationSubscriptionOperation (String userID, boolean enable);

    /**
     * @brief Register the callback defined by AIDL
     *
     * Register the callback defined by AIDL so that the SDK can send asynchronous events to the user.
     *
     * @see org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack for all possible events.
     * @param mcopCallBack Callback where the different events are sent.
     * @return Indicates whether the desired operation can be started.
     * @throws android.os.RemoteException
     */
    boolean registerCallback(IMCOPCallback mcopCallBack);

}