/******************************************************************************
 *
 *  Copyright 2021 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.
 *
 ******************************************************************************/


#include "bta_bap_uclient_api.h"
#include "ucast_client_int.h"
#include "bta_pacs_client_api.h"
#include "bta_ascs_client_api.h"
#include <hardware/bt_pacs_client.h>
#include <base/bind.h>
#include <base/callback.h>
#include <base/logging.h>
#include "bta_closure_api.h"
#include "bt_trace.h"

namespace bluetooth {
namespace bap {
namespace ucast {

using base::Bind;
using base::Unretained;
using base::Closure;
using bluetooth::Uuid;

using bluetooth::bap::pacs::PacsClient;
using bluetooth::bap::pacs::ConnectionState;
using bluetooth::bap::pacs::CodecConfig;
using bluetooth::bap::pacs::PacsClientCallbacks;

using bluetooth::bap::ascs::AscsClient;
using bluetooth::bap::ascs::GattState;
using bluetooth::bap::ascs::AscsClientCallbacks;
using bluetooth::bap::ascs::AseOpId;
using bluetooth::bap::ascs::AseOpStatus;
using bluetooth::bap::ascs::AseParams;

using bluetooth::bap::ucast::UstreamManagers;
using bluetooth::bap::ucast::UstreamManager;

using bluetooth::bap::ucast::BapEventData;
using bluetooth::bap::ucast::BapEvent;
using bluetooth::bap::ucast::BapConnect;
using bluetooth::bap::ucast::BapDisconnect;
using bluetooth::bap::ucast::BapStart;
using bluetooth::bap::ucast::BapStop;
using bluetooth::bap::ucast::BapReconfig;
using bluetooth::bap::ucast::PacsConnectionState;
using bluetooth::bap::ucast::PacsDiscovery;
using bluetooth::bap::ucast::PacsAvailableContexts;

using bluetooth::bap::ucast::CisGroupState;
using bluetooth::bap::ucast::CisStreamState;
using bluetooth::bap::cis::CigState;
using bluetooth::bap::cis::CisState;
using bluetooth::bap::cis::CisInterface;

using bluetooth::bap::alarm::BapAlarm;
using bluetooth::bap::alarm::BapAlarmCallbacks;

class UcastClientImpl;
UcastClientImpl* instance = nullptr;

class CisInterfaceCallbacksImpl : public CisInterfaceCallbacks {
  public:
    ~CisInterfaceCallbacksImpl() = default;
        /** Callback for connection state change */
    void OnCigState(uint8_t cig_id, CigState state) {
      do_in_bta_thread(FROM_HERE, Bind(&CisInterfaceCallbacks::OnCigState,
                                       Unretained(UcastClient::Get()), cig_id,
                                       state));

    }

    void OnCisState(uint8_t cig_id, uint8_t cis_id,
                   uint8_t direction, CisState state) {
      do_in_bta_thread(FROM_HERE, Bind(&CisInterfaceCallbacks::OnCisState,
                                       Unretained(UcastClient::Get()), cig_id,
                                       cis_id, direction, state));
    }
};

class PacsClientCallbacksImpl : public PacsClientCallbacks {
  public:
    ~PacsClientCallbacksImpl() = default;
    void OnInitialized(int status, int client_id) override {
      LOG(WARNING) << __func__ << ": status =" << loghex(status);
      do_in_bta_thread(FROM_HERE, Bind(&PacsClientCallbacks::OnInitialized,
                                       Unretained(UcastClient::Get()), status,
                                       client_id));
    }

    void OnConnectionState(const RawAddress& address,
                       bluetooth::bap::pacs::ConnectionState state) override {
      LOG(WARNING) << __func__ << ": address=" << address;
      do_in_bta_thread(FROM_HERE, Bind(&PacsClientCallbacks::OnConnectionState,
                                       Unretained(UcastClient::Get()),
                                       address, state));
    }

    void OnAudioContextAvailable(const RawAddress& address,
                          uint32_t available_contexts) override {
      do_in_bta_thread(FROM_HERE,
                       Bind(&PacsClientCallbacks::OnAudioContextAvailable,
                            Unretained(UcastClient::Get()),
                            address, available_contexts));
    }

    void OnSearchComplete(int status, const RawAddress& address,
                          std::vector<CodecConfig> sink_pac_records,
                          std::vector<CodecConfig> src_pac_records,
                          uint32_t sink_locations,
                          uint32_t src_locations,
                          uint32_t available_contexts,
                          uint32_t supported_contexts) override {
      do_in_bta_thread(FROM_HERE, Bind(&PacsClientCallbacks::OnSearchComplete,
                                       Unretained(UcastClient::Get()),
                                       status, address,
                                       sink_pac_records,
                                       src_pac_records,
                                       sink_locations,
                                       src_locations,
                                       available_contexts,
                                       supported_contexts));
    }
};

class AscsClientCallbacksImpl : public AscsClientCallbacks {
  public:
    ~AscsClientCallbacksImpl() = default;
    void OnAscsInitialized(int status, int client_id) override {
      do_in_bta_thread(FROM_HERE, Bind(&AscsClientCallbacks::OnAscsInitialized,
                                       Unretained(UcastClient::Get()), status,
                                       client_id));
    }

    void OnConnectionState(const RawAddress& address,
                       bluetooth::bap::ascs::GattState state) override {
      DVLOG(2) << __func__ << " address: " << address;
      do_in_bta_thread(FROM_HERE, Bind(&AscsClientCallbacks::OnConnectionState,
                                       Unretained(UcastClient::Get()),
                                       address, state));
    }

    void OnAseOpFailed(const RawAddress& address,
                             AseOpId ase_op_id,
                             std::vector<AseOpStatus> status) {
      do_in_bta_thread(FROM_HERE,
                       Bind(&AscsClientCallbacks::OnAseOpFailed,
                            Unretained(UcastClient::Get()),
                            address, ase_op_id, status));

    }

    void OnAseState(const RawAddress& address,
                          AseParams ase) override {
      do_in_bta_thread(FROM_HERE,
                       Bind(&AscsClientCallbacks::OnAseState,
                            Unretained(UcastClient::Get()),
                            address, ase));
    }

    void OnSearchComplete(int status, const RawAddress& address,
                          std::vector<AseParams> sink_ase_list,
                          std::vector<AseParams> src_ase_list) override {
      do_in_bta_thread(FROM_HERE, Bind(&AscsClientCallbacks::OnSearchComplete,
                                       Unretained(UcastClient::Get()),
                                       status, address, sink_ase_list,
                                       src_ase_list));
    }
};

class BapAlarmCallbacksImpl : public BapAlarmCallbacks {
  public:
    ~BapAlarmCallbacksImpl() = default;
    /** Callback for timer timeout */
    void OnTimeout(void* data) {
      do_in_bta_thread(FROM_HERE, Bind(&BapAlarmCallbacks::OnTimeout,
                                       Unretained(UcastClient::Get()), data));
    }
};

class UcastClientImpl : public UcastClient {
 public:
  ~UcastClientImpl() override = default;

  // APIs exposed for upper layers
  void Connect(std::vector<RawAddress> address, bool is_direct,
               std::vector<StreamConnect> streams) override {
    if(address.size() == 1) {
      UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address[0],
                                      pacs_client, pacs_client_id,
                                      ascs_client, cis_intf,
                                      ucl_callbacks, bap_alarm);
      // hand over the request to stream manager
      BapConnect data = { .bd_addr = address, .is_direct = is_direct,
                          .streams = streams};
      mgr->ProcessEvent(BAP_CONNECT_REQ_EVT, &data);
    }
  }

  void Disconnect(const RawAddress& address,
                  std::vector<StreamType> streams) override {
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);

    // hand over the request to stream manager
    BapDisconnect data = { .bd_addr = address,
                          .streams = streams};
    mgr->ProcessEvent(BAP_DISCONNECT_REQ_EVT, &data);
  }

  void Start(const RawAddress& address,
             std::vector<StreamType> streams) override {
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);

    // hand over the request to stream manager
    BapStart data = { .bd_addr = address,
                      .streams = streams};
    mgr->ProcessEvent(BAP_START_REQ_EVT, &data);
  }

  void Stop(const RawAddress& address,
            std::vector<StreamType> streams) override {
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);

    // hand over the request to stream manager
    BapStop data = { .bd_addr = address,
                     .streams = streams};
    mgr->ProcessEvent(BAP_STOP_REQ_EVT, &data);

  }

  void Reconfigure(const RawAddress& address,
                   std::vector<StreamReconfig> streams) override  {
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);

    // hand over the request to stream manager
    BapReconfig data = { .bd_addr = address,
                         .streams = streams};
    mgr->ProcessEvent(BAP_RECONFIG_REQ_EVT, &data);
  }

  void UpdateStream(const RawAddress& address,
                   std::vector<StreamUpdate> update_streams) override  {
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);

    // hand over the request to stream manager
    BapStreamUpdate data = { .bd_addr = address,
                            .update_streams = update_streams};
    mgr->ProcessEvent(BAP_STREAM_UPDATE_REQ_EVT, &data);
  }

  // To be called from device specific stream manager
  bool ReportStreamState(const RawAddress& address) {
    //TODO to check
    return true;

  }

  // PACS client related callbacks
  // to be forwarded to device specific stream manager
  void OnInitialized(int status, int client_id) override {
    LOG(WARNING) << __func__ << ": actual client_id = " << loghex(client_id);
    pacs_client_id = client_id;
  }

  void OnConnectionState(const RawAddress& address,
                         ConnectionState state) override {
    LOG(WARNING) << __func__ << ": address=" << address;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    PacsConnectionState data = { .bd_addr = address,
                                 .state = state
                               };
    mgr->ProcessEvent(PACS_CONNECTION_STATE_EVT, &data);
  }

  void OnAudioContextAvailable(const RawAddress& address,
                        uint32_t available_contexts) override {
    LOG(WARNING) << __func__ << ": address=" << address;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    PacsAvailableContexts data = {
                           .bd_addr = address,
                           .available_contexts = available_contexts,
                         };
    mgr->ProcessEvent(PACS_AUDIO_CONTEXT_RES_EVT, &data);
  }

  void OnSearchComplete(int status, const RawAddress& address,
                        std::vector<CodecConfig> sink_pac_records,
                        std::vector<CodecConfig> src_pac_records,
                        uint32_t sink_locations,
                        uint32_t src_locations,
                        uint32_t available_contexts,
                        uint32_t supported_contexts) override {
    LOG(WARNING) << __func__ << ": address=" << address;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    PacsDiscovery data = {
                           .status = status,
                           .bd_addr = address,
                           .sink_pac_records = sink_pac_records,
                           .src_pac_records = src_pac_records,
                           .sink_locations = sink_locations,
                           .src_locations = src_locations,
                           .available_contexts = available_contexts,
                           .supported_contexts = supported_contexts
                         };
    mgr->ProcessEvent(PACS_DISCOVERY_RES_EVT, &data);
  }

  // ASCS client related callbacks
  // to be forwarded to device specific stream manager
  void OnAscsInitialized(int status, int client_id) override {

  }

  void OnConnectionState(const RawAddress& address,
                     bluetooth::bap::ascs::GattState state) override {
    LOG(WARNING) << __func__ << ": address=" << address;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    AscsConnectionState data = { .bd_addr = address,
                                 .state = state
                               };
    mgr->ProcessEvent(ASCS_CONNECTION_STATE_EVT, &data);
  }

  void OnAseOpFailed(const RawAddress& address,
                     AseOpId ase_op_id,
                     std::vector<AseOpStatus> status) {

    LOG(WARNING) << __func__ << ": address=" << address;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    AscsOpFailed data = {
                           .bd_addr = address,
                           .ase_op_id = ase_op_id,
                           .ase_list = status
                        };
    mgr->ProcessEvent(ASCS_ASE_OP_FAILED_EVT, &data);
  }

  void OnAseState(const RawAddress& address,
                        AseParams ase_params) override {
    LOG(WARNING) << __func__ << ": address=" << address;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    AscsState data = {
                           .bd_addr = address,
                           .ase_params = ase_params
                     };
    mgr->ProcessEvent(ASCS_ASE_STATE_EVT, &data);
  }

  void OnSearchComplete(int status, const RawAddress& address,
                                std::vector<AseParams> sink_ase_list,
                                std::vector<AseParams> src_ase_list) override {
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(address,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    AscsDiscovery data = {
                           .status = status,
                           .bd_addr = address,
                           .sink_ases_list = sink_ase_list,
                           .src_ases_list = src_ase_list
                         };
    mgr->ProcessEvent(ASCS_DISCOVERY_RES_EVT, &data);
  }

  // cis callbacks
  void OnCigState(uint8_t cig_id, CigState state) override {
    std::vector<UstreamManager *> *mgrs_list =  strm_mgrs.GetAllManagers();
    // hand over the request to stream manager
    CisGroupState data = {
                      .cig_id = cig_id,
                      .state = state
                    };

    for (auto it = mgrs_list->begin(); it != mgrs_list->end(); it++) {
      (*it)->ProcessEvent(CIS_GROUP_STATE_EVT, &data);
    }
  }

  void OnCisState(uint8_t cig_id, uint8_t cis_id, uint8_t direction,
                                         CisState state) override {
    std::vector<UstreamManager *> *mgrs_list =  strm_mgrs.GetAllManagers();
    // hand over the request to stream manager
    CisStreamState data = {
                           .cig_id = cig_id,
                           .cis_id = cis_id,
                           .direction = direction,
                           .state = state
                         };

    for (auto it = mgrs_list->begin(); it != mgrs_list->end(); it++) {
      (*it)->ProcessEvent(CIS_STATE_EVT, &data);
    }
  }

  void OnTimeout(void* data) override {
    LOG(ERROR) << __func__;
    BapTimeout* data_ = (BapTimeout *)data;
    UstreamManager *mgr = strm_mgrs.FindorAddByAddress(data_->bd_addr,
                                    pacs_client, pacs_client_id,
                                    ascs_client, cis_intf,
                                    ucl_callbacks, bap_alarm);
    // hand over the request to stream manager
    mgr->ProcessEvent(BAP_TIME_OUT_EVT, data);
  }

  bool Init(UcastClientCallbacks *callback) {
    // register callbacks with CIS, ASCS client, PACS client
    pacs_callbacks = new PacsClientCallbacksImpl;
    PacsClient::Initialize(pacs_callbacks);
    pacs_client = PacsClient::Get();

    ascs_callbacks = new AscsClientCallbacksImpl;
    AscsClient::Init(ascs_callbacks);
    ascs_client = AscsClient::Get();

    cis_callbacks = new CisInterfaceCallbacksImpl;
    CisInterface::Initialize(cis_callbacks);
    cis_intf = CisInterface::Get();

    bap_alarm_cb = new BapAlarmCallbacksImpl;
    BapAlarm::Initialize(bap_alarm_cb);
    bap_alarm = BapAlarm::Get();

    pacs_client_id = 0;
    if(ucl_callbacks != nullptr) {
      // flag an error
      return false;
    } else {
      ucl_callbacks = callback;
      return true;
    }
  }

  bool CleanUp() {
    if(ucl_callbacks != nullptr) {
      ucl_callbacks = nullptr;
      //call clean ups for each clients(ascs, pacs, cis and bap_alarm)
      LOG(ERROR) << __func__
                 <<": Cleaning up pacs, ascs clients, cis intf and bap_alarm.";
      pacs_client->CleanUp(pacs_client_id);
      ascs_client->CleanUp(0x01);
      cis_intf->CleanUp();
      bap_alarm->CleanUp();
      pacs_client = nullptr;
      ascs_client = nullptr;
      cis_intf = nullptr;
      bap_alarm = nullptr;
      // remove all stream managers and other clean ups
      return true;
    } else {
      return false;
    }
  }

 private:
  UcastClientCallbacks* ucl_callbacks;
  UstreamManagers strm_mgrs;
  PacsClient *pacs_client;
  AscsClient *ascs_client;
  PacsClientCallbacks *pacs_callbacks;
  AscsClientCallbacks *ascs_callbacks;
  CisInterface *cis_intf;
  CisInterfaceCallbacks *cis_callbacks;
  uint16_t pacs_client_id;
  BapAlarm* bap_alarm;
  BapAlarmCallbacks* bap_alarm_cb;
};

void UcastClient::Initialize(UcastClientCallbacks* callbacks) {
  if (!instance) {
    instance = new UcastClientImpl();
    instance->Init(callbacks);
  } else {
    LOG(ERROR) << __func__ << " 2nd client registration ignored";
  }
}

void UcastClient::CleanUp() {
  if(instance && instance->CleanUp()) {
    delete instance;
    instance = nullptr;
  }
}

UcastClient* UcastClient::Get() {
  CHECK(instance);
  return instance;
}

}  // namespace ucast
}  // namespace bap
}  // namespace bluetooth
