// 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.

//! NCI API module

use crate::{CommandSender, LogicalConnectionsRegistry, Result};
use bytes::Bytes;
use log::{debug, error};
use nfc_hal::{HalEvent, HalEventRegistry, HalEventStatus};
use nfc_packets::nci::RfMappingConfiguration;
use nfc_packets::nci::{self, CommandBuilder, DataPacket, Opcode};
use nfc_packets::nci::{ConnCloseCommandBuilder, ConnCreateCommandBuilder};
use nfc_packets::nci::{DestParam, DestParamTypes, DestTypes};
use nfc_packets::nci::{FeatureEnable, PacketBoundaryFlag, ResetType};
use nfc_packets::nci::{InitCommandBuilder, ResetCommandBuilder};
use nfc_packets::nci::{InitResponse, ResponseChild};
use pdl_runtime::Packet;
use tokio::sync::oneshot;

type ConnCallback = fn(u8, u16, &[u8]);

struct NfcData {
    init_response: Option<InitResponse>,
    rf_callback: Option<ConnCallback>,
    hci_callback: Option<ConnCallback>,
}

type RespCallback = fn(u16, &[u8]);

/// NCI API object to manage static API data
pub struct NciApi {
    /// Command Sender external interface
    commands: Option<CommandSender>,
    /// Interface to Logical Connections Registry
    connections: Option<LogicalConnectionsRegistry>,
    /// The NFC response callback
    callback: Option<RespCallback>,
    /// HalEventRegistry is used to register for HAL events
    hal_events: Option<HalEventRegistry>,
    nfc_data: NfcData,
}

impl NciApi {
    /// NciApi constructor
    pub fn new() -> NciApi {
        let nfc_data = NfcData { init_response: None, rf_callback: None, hci_callback: None };
        NciApi { commands: None, connections: None, callback: None, hal_events: None, nfc_data }
    }

    /** ****************************************************************************
     **
     ** Function         nfc_enable
     **
     ** Description      This function enables NFC. Prior to calling NFC_Enable:
     **                  - the NFCC must be powered up, and ready to receive
     **                    commands.
     **
     **                  This function opens the NCI transport (if applicable),
     **                  resets the NFC controller, and initializes the NFC
     **                  subsystems.
     **
     **                  When the NFC startup procedure is completed, an
     **                  NFC_ENABLE_REVT is returned to the application using the
     **                  tNFC_RESPONSE_CBACK.
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    /// extern tNFC_STATUS NFC_Enable(tNFC_RESPONSE_CBACK* p_cback);
    pub async fn nfc_enable(&mut self, callback: RespCallback) {
        let nci = crate::init().await;

        self.commands = Some(nci.commands);
        self.connections = Some(nci.connections);
        self.callback = Some(callback);
        self.hal_events = Some(nci.hal_events);
    }
    /** ****************************************************************************
     **
     ** Function         NFC_Disable
     **
     ** Description      This function performs clean up routines for shutting down
     **                  NFC and closes the NCI transport (if using dedicated NCI
     **                  transport).
     **
     **                  When the NFC shutdown procedure is completed, an
     **                  NFC_DISABLED_REVT is returned to the application using the
     **                  tNFC_RESPONSE_CBACK.
     **
     ** Returns          nothing
     **
     *******************************************************************************/
    /// extern void NFC_Disable(void);
    pub async fn nfc_disable(&mut self) {
        let (tx, rx) = oneshot::channel::<HalEventStatus>();
        if let Some(mut event) = self.hal_events.take() {
            event.register(HalEvent::CloseComplete, tx).await;

            if let Some(cmd) = self.commands.take() {
                drop(cmd);
            }
            if let Some(conn) = self.connections.take() {
                drop(conn);
            }
            let status = rx.await.unwrap();
            debug!("Shutdown complete {:?}.", status);

            if let Some(cb) = self.callback.take() {
                cb(1, &[]);
            }
        }
    }

    /** ****************************************************************************
     **
     ** Function         NFC_Init
     **
     ** Description      This function initializes control blocks for NFC
     **
     ** Returns          nothing
     **
     *******************************************************************************/
    /// extern void NFC_Init(tHAL_NFC_ENTRY* p_hal_entry_tbl);
    pub async fn nfc_init(&mut self) -> Result<()> {
        let pbf = PacketBoundaryFlag::CompleteOrFinal;
        if let Some(cmd) = self.commands.as_mut() {
            let reset = cmd
                .send_and_notify(
                    ResetCommandBuilder { gid: 0, pbf, reset_type: ResetType::ResetConfig }
                        .build()
                        .into(),
                )
                .await?;
            let _notification_packet = reset.notification.await?;
            let init = cmd
                .send(
                    InitCommandBuilder { gid: 0, pbf, feature_enable: FeatureEnable::Rfu }
                        .build()
                        .into(),
                )
                .await?;
            if let ResponseChild::InitResponse(irp) = init.specialize() {
                if let Some(conn) = self.connections.as_mut() {
                    // Open static RF connection
                    // TODO: use channels instead of callcacks here
                    // the data can be tranlated to c-callback at the shim level
                    conn.open(0, self.nfc_data.rf_callback, 0, 0).await;
                    // Open static HCI connection
                    conn.open(
                        1, /* TODO: link constants to the c header */
                        self.nfc_data.hci_callback,
                        irp.get_max_data_payload(),
                        irp.get_num_of_credits(),
                    )
                    .await;
                }
                self.nfc_data.init_response = Some(irp);
            }
        }
        Ok(())
    }

    /** *****************************************************************************
     **
     ** Function         NFC_GetLmrtSize
     **
     ** Description      Called by application wto query the Listen Mode Routing
     **                  Table size supported by NFCC
     **
     ** Returns          Listen Mode Routing Table size
     **
     *******************************************************************************/
    /// extern uint16_t NFC_GetLmrtSize(void);
    pub async fn nfc_get_lmrt_size(&mut self) -> u16 {
        if let Some(ir) = &self.nfc_data.init_response {
            ir.get_max_rout_tbls_size()
        } else {
            0
        }
    }

    /** *****************************************************************************
     **
     ** Function         NFC_SetConfig
     **
     ** Description      This function is called to send the configuration parameter
     **                  TLV to NFCC. The response from NFCC is reported by
     **                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
     **
     ** Parameters       tlv_size - the length of p_param_tlvs.
     **                  p_param_tlvs - the parameter ID/Len/Value list
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    /// extern tNFC_STATUS NFC_SetConfig(uint8_t tlv_size, uint8_t* p_param_tlvs);
    pub async fn nfc_set_config(&mut self, param_tlvs: &[u8]) -> Result<u8> {
        let pbf = PacketBoundaryFlag::CompleteOrFinal;
        if let Some(cmd) = self.commands.as_mut() {
            let raw = cmd
                .send(
                    CommandBuilder {
                        gid: 0,
                        pbf,
                        op: Opcode::CoreSetConfig,
                        payload: Some(Bytes::copy_from_slice(param_tlvs)),
                    }
                    .build(),
                )
                .await?
                .encode_to_bytes()?;
            if let Some(cb) = self.callback {
                cb(2, &raw[3..]);
            }
            Ok(raw[3])
        } else {
            Ok(nci::Status::NotInitialized as u8)
        }
    }

    /** *****************************************************************************
     **
     ** Function         NFC_GetConfig
     **
     ** Description      This function is called to retrieve the parameter TLV from
     **                  NFCC. The response from NFCC is reported by
     **                  tNFC_RESPONSE_CBACK as NFC_GET_CONFIG_REVT.
     **
     ** Parameters       num_ids - the number of parameter IDs
     **                  p_param_ids - the parameter ID list.
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    /// extern tNFC_STATUS NFC_GetConfig(uint8_t num_ids, uint8_t* p_param_ids);
    pub async fn nfc_get_config(&mut self, param_tlvs: &[u8]) -> Result<u8> {
        let pbf = PacketBoundaryFlag::CompleteOrFinal;
        if let Some(cmd) = self.commands.as_mut() {
            let raw = cmd
                .send(
                    CommandBuilder {
                        gid: 0,
                        pbf,
                        op: Opcode::CoreGetConfig,
                        payload: Some(Bytes::copy_from_slice(param_tlvs)),
                    }
                    .build(),
                )
                .await?
                .encode_to_bytes()?;
            if let Some(cb) = self.callback {
                cb(3, &raw[3..]);
            }
            Ok(raw[3])
        } else {
            Ok(nci::Status::NotInitialized as u8)
        }
    }
    /** ****************************************************************************
     **
     ** Function         NFC_ConnCreate
     **
     ** Description      This function is called to create a logical connection with
     **                  NFCC for data exchange.
     **                  The response from NFCC is reported in tNFC_CONN_CBACK
     **                  as NFC_CONN_CREATE_CEVT.
     **
     ** Parameters       dest_type - the destination type
     **                  id   - the NFCEE ID or RF Discovery ID .
     **                  protocol - the protocol
     **                  p_cback - the data callback function to receive data from
     **                  NFCC
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    //extern tNFC_STATUS NFC_ConnCreate(uint8_t dest_type, uint8_t id,
    //                                  uint8_t protocol, tNFC_CONN_CBACK* p_cback);
    pub async fn nfc_conn_create(
        &mut self,
        dest_type: u8,
        id: u8,
        protocol: u8,
        callback: ConnCallback,
    ) -> Result<u8> {
        let pbf = PacketBoundaryFlag::CompleteOrFinal;
        let mut destparams: Vec<DestParam> = vec![];
        let dt = DestTypes::try_from(dest_type).unwrap();
        match dt {
            DestTypes::NfccLpbk => (),
            DestTypes::Remote => {
                let parameter = vec![id, protocol];
                destparams.push(DestParam { ptype: DestParamTypes::RfDisc, parameter });
            }
            DestTypes::Nfcee => {
                let parameter: Vec<u8> = vec![id, protocol];
                destparams.push(DestParam { ptype: DestParamTypes::Nfcee, parameter });
            }
            _ => return Ok(nci::Status::InvalidParam as u8),
        }
        if let Some(cmd) = self.commands.as_mut() {
            let rp = cmd
                .send(ConnCreateCommandBuilder { gid: 0, pbf, dt, destparams }.build().into())
                .await?;
            if let ResponseChild::ConnCreateResponse(ccrp) = rp.specialize() {
                let status = ccrp.get_status();
                if status == nci::Status::Ok {
                    if let Some(conn) = self.connections.as_mut() {
                        conn.open(
                            ccrp.get_conn_id(),
                            Some(callback),
                            ccrp.get_mpps(),
                            ccrp.get_ncreds(),
                        )
                        .await;
                        let conn_create_evt =
                            [status as u8, dest_type, id, ccrp.get_mpps(), ccrp.get_ncreds()];
                        callback(ccrp.get_conn_id(), 0, &conn_create_evt[..]);
                    } else {
                        return Ok(nci::Status::NotInitialized as u8);
                    }
                }
                Ok(status as u8)
            } else {
                Ok(nci::Status::Failed as u8)
            }
        } else {
            Ok(nci::Status::NotInitialized as u8)
        }
    }

    /** ****************************************************************************
     **
     ** Function         NFC_ConnClose
     **
     ** Description      This function is called to close a logical connection with
     **                  NFCC.
     **                  The response from NFCC is reported in tNFC_CONN_CBACK
     **                  as NFC_CONN_CLOSE_CEVT.
     **
     ** Parameters       conn_id - the connection id.
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    //extern tNFC_STATUS NFC_ConnClose(uint8_t conn_id);
    pub async fn nfc_conn_close(&mut self, conn_id: u8) -> Result<u8> {
        let pbf = PacketBoundaryFlag::CompleteOrFinal;
        if let Some(conn) = self.connections.as_mut() {
            if let Some(cb) = conn.close(conn_id).await {
                if let Some(cmd) = self.commands.as_mut() {
                    let rp = cmd
                        .send(ConnCloseCommandBuilder { gid: 0, pbf, conn_id }.build().into())
                        .await?;
                    if let ResponseChild::ConnCloseResponse(ccrp) = rp.specialize() {
                        let status = ccrp.get_status() as u8;
                        let conn_close_evt = [status];
                        cb(conn_id, 1, &conn_close_evt[..]);
                        return Ok(status);
                    } else {
                        return Ok(nci::Status::Failed as u8);
                    }
                }
            } else {
                return Ok(nci::Status::InvalidParam as u8);
            }
        }
        Ok(nci::Status::NotInitialized as u8)
    }

    /** *****************************************************************************
     **
     ** Function         NFC_SetStaticRfCback
     **
     ** Description      This function is called to update the data callback function
     **                  to receive the data for the given connection id.
     **
     ** Parameters       p_cback - the connection callback function
     **
     ** Returns          Nothing
     **
     *******************************************************************************/
    //extern void NFC_SetStaticRfCback(tNFC_CONN_CBACK* p_cback);
    pub async fn nfc_set_static_rf_callback(&mut self, callback: ConnCallback) {
        self.nfc_data.rf_callback = Some(callback);
        if let Some(conn) = self.connections.as_mut() {
            conn.set_static_callback(0, Some(callback)).await;
        }
    }

    /** *****************************************************************************
     **
     ** Function         NFC_SetStaticHciCback
     **
     ** Description      This function to update the data callback function
     **                  to receive the data for the static Hci connection id.
     **
     ** Parameters       p_cback - the connection callback function
     **
     ** Returns          Nothing
     **
     *******************************************************************************/
    //extern void NFC_SetStaticHciCback(tNFC_CONN_CBACK* p_cback);
    pub async fn nfc_set_static_hci_callback(&mut self, callback: ConnCallback) {
        self.nfc_data.hci_callback = Some(callback);
        if let Some(conn) = self.connections.as_mut() {
            conn.set_static_callback(1, Some(callback)).await;
        }
    }

    /*******************************************************************************
     **
     ** Function         NFC_SetReassemblyFlag
     **
     ** Description      This function is called to set if nfc will reassemble
     **                  nci packet as much as its buffer can hold or it should not
     **                  reassemble but forward the fragmented nci packet to layer
     **                  above. If nci data pkt is fragmented, nfc may send multiple
     **                  NFC_DATA_CEVT with status NFC_STATUS_CONTINUE before sending
     **                  NFC_DATA_CEVT with status NFC_STATUS_OK based on reassembly
     **                  configuration and reassembly buffer size
     **
     ** Parameters       reassembly - flag to indicate if nfc may reassemble or not
     **
     ** Returns          Nothing
     **
     *******************************************************************************/
    //extern void NFC_SetReassemblyFlag(bool reassembly);

    /** ****************************************************************************
     **
     ** Function         NFC_SendData
     **
     ** Description      This function is called to send the given data packet
     **                  to the connection identified by the given connection id.
     **
     ** Parameters       conn_id - the connection id.
     **                  p_data - the data packet
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    //extern tNFC_STATUS NFC_SendData(uint8_t conn_id, NFC_HDR* p_data);
    pub async fn nfc_send_data(&mut self, conn_id: u8, data: &[u8]) -> Result<u8> {
        if let Some(conn) = self.connections.as_mut() {
            match DataPacket::parse(data) {
                Ok(pkt) => {
                    conn.send_packet(conn_id, pkt).await;
                    return Ok(nci::Status::Ok as u8);
                }
                Err(e) => {
                    error!("Data packet is invalid:{:?}", e);
                    return Ok(nci::Status::InvalidParam as u8);
                }
            }
        }
        Ok(nci::Status::NotInitialized as u8)
    }

    /** ****************************************************************************
     **
     ** Function         NFC_FlushData
     **
     ** Description      This function is called to discard the tx data queue of
     **                  the given connection id.
     **
     ** Parameters       conn_id - the connection id.
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    //extern tNFC_STATUS NFC_FlushData(uint8_t conn_id);
    pub async fn nfc_flush_data(&mut self, conn_id: u8) -> Result<u8> {
        if let Some(conn) = self.connections.as_mut() {
            if conn.flush_data(conn_id).await {
                Ok(nci::Status::Ok as u8)
            } else {
                Ok(nci::Status::Failed as u8)
            }
        } else {
            Ok(nci::Status::NotInitialized as u8)
        }
    }

    /** ****************************************************************************
     **
     ** Function         NFC_DiscoveryMap
     **
     ** Description      This function is called to set the discovery interface
     **                  mapping. The response from NFCC is reported by
     **                  tNFC_DISCOVER_CBACK as. NFC_MAP_DEVT.
     **
     ** Parameters       num - the number of items in p_params.
     **                  p_maps - the discovery interface mappings
     **                  p_cback - the discovery callback function
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    // extern tNFC_STATUS NFC_DiscoveryMap(uint8_t num, tNFC_DISCOVER_MAPS* p_maps,
    //                                    tNFC_DISCOVER_CBACK* p_cback);
    pub async fn nfc_discovery_map(&mut self, _maps: Vec<RfMappingConfiguration>) -> Result<u8> {
        Ok(0)
    }

    /*******************************************************************************
     **
     ** Function         NFC_DiscoveryStart
     **
     ** Description      This function is called to start Polling and/or Listening.
     **                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
     **                  as NFC_START_DEVT. The notification from NFCC is reported by
     **                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
     **
     ** Parameters       num_params - the number of items in p_params.
     **                  p_params - the discovery parameters
     **                  p_cback - the discovery callback function
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    // extern tNFC_STATUS NFC_DiscoveryStart(uint8_t num_params,
    //                                       tNFC_DISCOVER_PARAMS* p_params,
    //                                       tNFC_DISCOVER_CBACK* p_cback);

    /*******************************************************************************
     **
     ** Function         NFC_DiscoverySelect
     **
     ** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
     **                  the application needs to use this function to select the
     **                  the logical endpoint to continue. The response from NFCC is
     **                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
     **
     ** Parameters       rf_disc_id - The ID identifies the remote device.
     **                  protocol - the logical endpoint on the remote device
     **                  rf_interface - the RF interface to communicate with NFCC
     **
     ** Returns          tNFC_STATUS
     **
     *******************************************************************************/
    // extern tNFC_STATUS NFC_DiscoverySelect(uint8_t rf_disc_id, uint8_t protocol,
    //                                        uint8_t rf_interface);
}

impl Default for NciApi {
    fn default() -> Self {
        Self::new()
    }
}
