/******************************************************************************
 *
 *  Copyright 2016 The Android Open Source Project
 *  Copyright 2009-2012 Broadcom Corporation
 *
 *  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.
 *
 ******************************************************************************/

#define LOG_TAG "bt_btif_a2dp"

#include "btif_a2dp.h"

#include <stdbool.h>

#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
#include "audio_hal_interface/a2dp_encoding.h"
#include "bta_av_api.h"
#include "btif_a2dp_control.h"
#include "btif_a2dp_sink.h"
#include "btif_a2dp_source.h"
#include "btif_av.h"
#include "btif_av_co.h"
#include "btif_hf.h"
#include "btif_util.h"
#include "osi/include/log.h"
#include "types/raw_address.h"

#include <base/logging.h>

void btif_a2dp_on_idle(void) {
  LOG_VERBOSE("Peer stream endpoint type:%s",
              peer_stream_endpoint_text(btif_av_get_peer_sep()).c_str());
  if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
    btif_a2dp_source_on_idle();
  } else if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
    btif_a2dp_sink_on_idle();
  }
}

bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start) {
  LOG(INFO) << __func__ << ": ## ON A2DP STARTED ## peer " << peer_addr << " p_av_start:" << p_av_start;

  if (p_av_start == NULL) {
    tA2DP_CTRL_ACK status = A2DP_CTRL_ACK_SUCCESS;
    if (!bluetooth::headset::IsCallIdle()) {
      LOG(ERROR) << __func__ << ": peer " << peer_addr << " call in progress, do not start A2DP stream";
      status = A2DP_CTRL_ACK_INCALL_FAILURE;
    }
    /* just ack back a local start request, do not start the media encoder since
     * this is not for BTA_AV_START_EVT. */
    if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
      bluetooth::audio::a2dp::ack_stream_started(status);
    } else {
      btif_a2dp_command_ack(status);
    }
    return true;
  }

  LOG(INFO) << __func__ << ": peer " << peer_addr << " status:" << +p_av_start->status
            << " suspending:" << logbool(p_av_start->suspending) << " initiator:" << logbool(p_av_start->initiator);

  if (p_av_start->status == BTA_AV_SUCCESS) {
    if (p_av_start->suspending) {
      LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event";
      return false;
    }
    if (btif_av_is_a2dp_offload_running()) {
      btif_av_stream_start_offload();
    } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
      if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
        /* Start the media encoder to do the SW audio stream */
        btif_a2dp_source_start_audio_req();
      }
      if (p_av_start->initiator) {
        bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_SUCCESS);
        return true;
      }
    } else {
      if (p_av_start->initiator) {
        btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
        return true;
      }
      /* media task is auto-started upon UIPC connection of a2dp audiopath */
    }
  } else if (p_av_start->initiator) {
    LOG(ERROR) << __func__ << ": peer " << peer_addr << " A2DP start request failed: status = " << +p_av_start->status;
    if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
      bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE);
    } else {
      btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
    }
    return true;
  }
  return false;
}

void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
  LOG_INFO("%s: ## ON A2DP STOPPED ## p_av_suspend=%p", __func__, p_av_suspend);

  if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
    btif_a2dp_sink_on_stopped(p_av_suspend);
    return;
  }
  if (bluetooth::audio::a2dp::is_hal_2_0_enabled() ||
      !btif_av_is_a2dp_offload_running()) {
    btif_a2dp_source_on_stopped(p_av_suspend);
  }
}

void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
  LOG_INFO("%s: ## ON A2DP SUSPENDED ## p_av_suspend=%p", __func__,
           p_av_suspend);
  if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
    btif_a2dp_sink_on_suspended(p_av_suspend);
    return;
  }
  if (bluetooth::audio::a2dp::is_hal_2_0_enabled() ||
      !btif_av_is_a2dp_offload_running()) {
    btif_a2dp_source_on_suspended(p_av_suspend);
  }
}

void btif_a2dp_on_offload_started(const RawAddress& peer_addr,
                                  tBTA_AV_STATUS status) {
  tA2DP_CTRL_ACK ack;
  LOG_INFO("%s: peer %s status %d", __func__, peer_addr.ToString().c_str(),
           status);

  switch (status) {
    case BTA_AV_SUCCESS:
      ack = A2DP_CTRL_ACK_SUCCESS;
      break;
    case BTA_AV_FAIL_RESOURCES:
      LOG_ERROR("%s: peer %s FAILED UNSUPPORTED", __func__,
                peer_addr.ToString().c_str());
      ack = A2DP_CTRL_ACK_UNSUPPORTED;
      break;
    default:
      LOG_ERROR("%s: peer %s FAILED: status = %d", __func__,
                peer_addr.ToString().c_str(), status);
      ack = A2DP_CTRL_ACK_FAILURE;
      break;
  }
  if (btif_av_is_a2dp_offload_running()) {
    if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) {
      // Offload request will return with failure from btif_av sm if
      // suspend is triggered for remote start. Disconnect only if SoC
      // returned failure for offload VSC
      LOG_ERROR("%s: peer %s offload start failed", __func__,
                peer_addr.ToString().c_str());
      btif_av_src_disconnect_sink(peer_addr);
    }
  }
  if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
    bluetooth::audio::a2dp::ack_stream_started(ack);
  } else {
    btif_a2dp_command_ack(ack);
  }
}

void btif_debug_a2dp_dump(int fd) {
  btif_a2dp_source_debug_dump(fd);
  btif_a2dp_sink_debug_dump(fd);
  btif_a2dp_codec_debug_dump(fd);
}
