/*
 * Copyright 2020 The Android Open Source Project
 *
 * 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 android.uwb;

import android.os.PersistableBundle;
import android.uwb.LogicalLinkCreationParams;
import android.uwb.LogicalLinkConnectionRequest;
import android.uwb.RangingChangeReason;
import android.uwb.RangingReport;
import android.uwb.SessionHandle;
import android.uwb.UwbAddress;

/**
 * @hide
 * TODO(b/211025367): Remove all the duplicate javadocs here.
 */
oneway interface IUwbRangingCallbacks {
  /**
   * Called when the ranging session has been opened
   *
   * @param sessionHandle the session the callback is being invoked for
   */
  void onRangingOpened(in SessionHandle sessionHandle);

  /**
   * Called when a ranging session fails to start
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason the reason the session failed to start
   * @param parameters protocol specific parameters
   */
  void onRangingOpenFailed(in SessionHandle sessionHandle,
                           RangingChangeReason reason,
                           in PersistableBundle parameters);

  /**
   * Called when ranging has started
   *
   * May output parameters generated by the lower layers that must be sent to the
   * remote device(s). The PersistableBundle must be constructed using the UWB
   * support library.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param rangingOutputParameters parameters generated by the lower layer that
   *                                should be sent to the remote device.
   */
  void onRangingStarted(in SessionHandle sessionHandle,
                        in PersistableBundle parameters);

  /**
   * Called when a ranging session fails to start
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason the reason the session failed to start
   * @param parameters protocol specific parameters
   */
  void onRangingStartFailed(in SessionHandle sessionHandle,
                            RangingChangeReason reason,
                            in PersistableBundle parameters);

   /**
   * Called when ranging has been reconfigured
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param parameters the updated ranging configuration
   */
  void onRangingReconfigured(in SessionHandle sessionHandle,
                             in PersistableBundle parameters);

  /**
   * Called when a ranging session fails to be reconfigured
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason the reason the session failed to reconfigure
   * @param parameters protocol specific parameters
   */
  void onRangingReconfigureFailed(in SessionHandle sessionHandle,
                                  RangingChangeReason reason,
                                  in PersistableBundle parameters);

  /**
   * Called when the ranging session has been stopped
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason the reason the session was stopped
   * @param parameters protocol specific parameters
   */

  void onRangingStopped(in SessionHandle sessionHandle,
                        RangingChangeReason reason,
                        in PersistableBundle parameters);

  /**
   * Called when a ranging session fails to stop
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason the reason the session failed to stop
   * @param parameters protocol specific parameters
   */
  void onRangingStopFailed(in SessionHandle sessionHandle,
                           RangingChangeReason reason,
                           in PersistableBundle parameters);

  /**
   * Called when a ranging session is closed
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason the reason the session was closed
   * @param parameters protocol specific parameters
   */
  void onRangingClosed(in SessionHandle sessionHandle,
                       RangingChangeReason reason,
                       in PersistableBundle parameters);

  /**
   * Provides a new RangingResult to the framework
   *
   * The reported timestamp for a ranging measurement must be calculated as the
   * time which the ranging round that generated this measurement concluded.
   *
   * @param sessionHandle an identifier to associate the ranging results with a
   *                      session that is active
   * @param result the ranging report
   */
  void onRangingResult(in SessionHandle sessionHandle, in RangingReport result);

  /**
   * Invoked when a new controlee is added to an ongoing one-to many session.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param parameters protocol specific parameters for the new controlee.
   */
  void onControleeAdded(in SessionHandle sessionHandle, in PersistableBundle parameters);

  /**
   * Invoked when a new controlee is added to an ongoing one-to many session.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason reason for the controlee add failure.
   * @param parameters protocol specific parameters related to the failure.
   */
  void onControleeAddFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when an existing controlee is removed from an ongoing one-to many session.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param parameters protocol specific parameters for the existing controlee.
   */
  void onControleeRemoved(in SessionHandle sessionHandle, in PersistableBundle parameters);

  /**
   * Invoked when a new controlee is added to an ongoing one-to many session.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason reason for the controlee remove failure.
   * @param parameters protocol specific parameters related to the failure.
   */
  void onControleeRemoveFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when an ongoing session is successfully suspended.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param parameters protocol specific parameters sent for suspension.
   */
  void onRangingPaused(in SessionHandle sessionHandle, in PersistableBundle parameters);

  /**
   * Invoked when an ongoing session suspension fails.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason reason for the suspension failure.
   * @param parameters protocol specific parameters for suspension failure.
   */
  void onRangingPauseFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when a suspended session is successfully resumed.
   *
   * @param parameters protocol specific parameters sent for suspension.
   */
  void onRangingResumed(in SessionHandle sessionHandle, in PersistableBundle parameters);

  /**
   * Invoked when a suspended session resumption fails.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param reason reason for the resumption failure.
   * @param parameters protocol specific parameters for resumption failure.
   */
  void onRangingResumeFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when data is successfully sent via {@link RangingSession#sendData(UwbAddress,
   * PersistableBundle, byte[])}.
   *
   * <p>Note: In Logical Link Mode, {@code remoteDeviceAddress} is not applicable and should
   * be ignored. The destination is identified using the Logical Link Connect ID in
   * {@code parameters}.
   *
   * @param sessionHandle the session the callback is being invoked for.
   * @param remoteDeviceAddress Address of the target device (not used in Logical Link Mode).
   * @param parameters protocol specific parameters used during send data.
   */
  void onDataSent(in SessionHandle sessionHandle, in UwbAddress remoteDeviceAddress,
          in PersistableBundle parameters);

  /**
   * Invoked when data send to a remote device via {@link RangingSession#sendData(UwbAddress,
   * PersistableBundle, byte[])} fails.
   *
   * <p>Note: In Logical Link Mode, {@code remoteDeviceAddress} is not applicable and should
   * be ignored. The destination is identified using the Logical Link Connect ID in
   * {@code parameters}.
   *
   * @param sessionHandle the session the callback is being invoked for.
   * @param remoteDeviceAddress Address of the target device (not used in Logical Link Mode).
   * @param reason reason for the send data failure.
   * @param parameters protocol specific parameters used during send data.
   */
  void onDataSendFailed(in SessionHandle sessionHandle, in UwbAddress remoteDeviceAddress,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when set data transfer phase config via {@link RangingSession#
   * setDataTransferPhaseConfig(in SessionHandle sessionHandle, in PersistableBundle params)}
   * succeeds.
   *
   * @param sessionHandle the session for which the callback is being invoked for
   * @param parameters protocol specific parameters for set data transfer phase config success.
   */
  void onDataTransferPhaseConfigured(in SessionHandle sessionHandle,
        in PersistableBundle parameters);

  /**
   * Invoked when set data transfer phase config via {@link RangingSession#
   * setDataTransferPhaseConfig(in SessionHandle sessionHandle, in PersistableBundle params)} fails.
   *
   * @param sessionHandle the session for which the callback is being invoked for
   * @param parameters protocol specific parameters for set data transfer phase config failure.
   */
  void onDataTransferPhaseConfigFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Callback triggered when data is received from a remote device.
   *
   * <p>This supports two link layer modes:
   *
   * <ul>
   *   <li><b>Bypass Mode (FiRa 2.0+):</b>
   *      The data is received piggybacked over RRM (initiator -> responder) or
   *      RIM (responder -> initiator).
   *     <ul>
   *       <li>`remoteDeviceAddress` is the actual address of the sender.</li>
   *       <li>`parameters` may be empty or protocol-specific.</li>
   *     </ul>
   *   </li>
   *
   *   <li><b>Logical Link Mode (FiRa 3.0+):</b>
   *     <ul>
   *       <li>`remoteDeviceAddress` is always set to {@code 0xFFFF}.</li>
   *       <li>`parameters` will include the Logical Link Connect ID (key: "connect_id").</li>
   *     </ul>
   *   </li>
   * </ul>
   *
   * @param sessionHandle         the session for which the callback is invoked.
   * @param remoteDeviceAddress   UWB address of the remote device (or {@code 0xFFFF} for
   *                              Logical Link mode).
   * @param parameters            protocol-specific data (e.g., connectId in Logical Link mode).
   * @param data                  raw payload received.
   */
  void onDataReceived(in SessionHandle sessionHandle, in UwbAddress remoteDeviceAddress,
          in PersistableBundle parameters, in byte[] data);

  /**
   * Invoked when data receive from a remote device fails.
   *
   * @param sessionHandle the session the callback is being invoked for
   * @param remoteDeviceAddress remote device's address.
   * @param reason reason for the resumption failure.
   * @param parameters protocol specific parameters for resumption failure.
   */
  void onDataReceiveFailed(in SessionHandle sessionHandle, in UwbAddress remoteDeviceAddress,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when set hybrid session controller configuration via {@link RangingSession#
   * setHybridSessionControllerConfiguration(
   * in SessionHandle sessionHandle, in PersistableBundle params)} succeeds.
   *
   * @param sessionHandle the session for which the callback is being invoked for.
   * @param parameters protocol specific parameters for set hybrid session controller config
   * success.
   */
  void onHybridSessionControllerConfigured(in SessionHandle sessionHandle,
          in PersistableBundle parameters);

  /**
   * Invoked when set hybrid session controller configuration via {@link RangingSession#
   * setHybridSessionControllerConfiguration(
   * in SessionHandle sessionHandle, in PersistableBundle params)} fails.
   *
   * @param sessionHandle the session for which the callback is being invoked for.
   * @param parameters protocol specific parameters for set hybrid session controller config
   * failure.
   */
  void onHybridSessionControllerConfigurationFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Invoked when set hybrid session Controlee configuration via {@link RangingSession#
   * setHybridSessionControleeConfiguration(
   * in SessionHandle sessionHandle, in PersistableBundle params)} succeeds.
   *
   * @param sessionHandle the session for which the callback is being invoked for.
   * @param parameters protocol specific parameters for set hybrid session Controlee config
   * success.
   */
  void onHybridSessionControleeConfigured(in SessionHandle sessionHandle,
          in PersistableBundle parameters);

  /**
   * Called when the controller dynamically updates the device role of a controlee during a
   * time-scheduled Two-Way Ranging (TWR) session.
   *
   * @param sessionHandle the session for which the callback is being invoked for.
   * @param deviceRole The new device role assigned to the controlee.
   */
  void onControleeRoleChanged(in SessionHandle sessionHandle, in int deviceRole);

  /**
   * Invoked when set hybrid session Controlee configuration via {@link RangingSession#
   * setHybridSessionControleeConfiguration(
   * in SessionHandle sessionHandle, in PersistableBundle params)} fails.
   *
   * @param sessionHandle the session for which the callback is being invoked for.
   * @param parameters protocol specific parameters for set hybrid session Controlee config
   * failure.
   */
  void onHybridSessionControleeConfigurationFailed(in SessionHandle sessionHandle,
          RangingChangeReason reason, in PersistableBundle parameters);

  /**
   * Callback invoked when a logical link is successfully created following a call to
   * {@link RangingSession#createLogicalLink(LogicalLinkCreationParams)}.
   *
   * <p>This method indicates that the logical link was successfully established. The assigned
   * {@code connectId} can be used for subsequent communication over this link.</p>
   *
   * @param sessionHandle The session handle associated with the logical link.
   * @param params {@link LogicalLinkCreationParams} used during the link creation.
   * @param connectId The connection ID assigned to the newly created logical link.
   */
  void onLogicalLinkCreated(in SessionHandle sessionHandle, in LogicalLinkCreationParams params,
        in int connectId);

  /**
   * Callback invoked when the logical link creation fails following a call to
   * {@link RangingSession#createLogicalLink(LogicalLinkCreationParams)}.
   *
   * <p>This method notifies the application that the attempt to establish a logical link was
   * unsuccessful. Refer to the {@code status} for failure details.</p>
   *
   * @param sessionHandle The session handle associated with the logical link attempt.
   * @param params {@link LogicalLinkCreationParams} used during the link creation.
   * @param status The status code indicating the reason for failure.
   *                   See {@link LogicalLinkStatusCode} for possible values.
   */
  void onLogicalLinkCreationFailed(in SessionHandle sessionHandle, in LogicalLinkCreationParams
      params, in int status);

  /**
   * Callback invoked when a logical link is closed, either as a result of a
   * {@link RangingSession#closeLogicalLink(int)} request or due to remote termination, link
   * failure, timeout, or other UWBS-initiated conditions.
   *
   * <p>This method is called only for logical links that were previously open. The closure reason
   * indicates whether the closure was initiated by the host or due to other conditions such as
   * remote device actions, transmission errors, timeouts, or intervention by the secure
   * component.</p>
   *
   * @param sessionHandle The handle of the session to which the closed logical link belonged.
   * @param connectId Unique identifier of the logical link that was closed.
   * @param reason Reason for link closure. See {@link LogicalLinkClosureReason} for valid values.
   */
  void onLogicalLinkClosed(in SessionHandle sessionHandle, in int connectId, in int reason);

  /**
   * Callback invoked when closing a logical link fails after calling
   * {@link RangingSession#closeLogicalLink(int)}.
   *
   * @param connectId The connection ID associated with the logical link.
   * @param status The failure status code indicating why the close failed.
   *                   See {@link LogicalLinkStatusCode} for possible values.
   */
  void onLogicalLinkClosureFailed(in SessionHandle sessionHandle, in int connectId, in int status);

  /**
   * Callback invoked when a remote device requests to establish a logical link.
   *
   * <p>This notification occurs in the following cases:
   * <ul>
   *   <li>The Controlee UWBS receives a request from the Controller to establish a
   *        connection-oriented (CO) logical link.</li>
   *   <li>Initial connectionless (CL) data is received during a data-only or data-with-ranging
   *        session.</li>
   * </ul>
   *
   * <p>If the host application does not approve the link, it must call
   * {@link #closeLogicalLink(int)} with the {@code connectId} provided in this callback.
   * Otherwise, the host and UWBS will use the {@code connectId} for all subsequent
   * application data exchanges on this logical link.
   *
   * @param sessionHandle Identifies the ongoing data transfer or ranging session.
   * @param LogicalLinkConnectionRequest Information about the requested logical link.
   */
  void onRemoteLogicalLinkRequested(in SessionHandle sessionHandle,
          in LogicalLinkConnectionRequest linkInfo);

  void onServiceDiscovered(in SessionHandle sessionHandle, in PersistableBundle parameters);

  void onServiceConnected(in SessionHandle sessionHandle, in PersistableBundle parameters);

  void onRangingRoundsUpdateDtTagStatus(in SessionHandle sessionHandle,
            in PersistableBundle parameters);
}
