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

//! Rootcanal HAL
//! This connects to "rootcanal" which provides a simulated
//! Nfc chip as well as a simulated environment.

use crate::internal::InnerHal;
use crate::{is_control_packet, Hal, HalEvent, HalEventRegistry, HalEventStatus, Result};
use bytes::{BufMut, BytesMut};
use log::{debug, error};
use nfc_packets::nci::{DataPacket, NciPacket};
use pdl_runtime::Packet;
use std::convert::TryInto;
use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::net::TcpStream;
use tokio::select;
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};

/// Initialize the module
pub async fn init() -> Hal {
    let (raw_hal, inner_hal) = InnerHal::new();
    let (reader, writer) = TcpStream::connect("127.0.0.1:7000")
        .await
        .expect("unable to create stream to rootcanal")
        .into_split();

    let reader = BufReader::new(reader);
    tokio::spawn(dispatch_incoming(inner_hal.in_cmd_tx, inner_hal.in_data_tx, reader));
    tokio::spawn(dispatch_outgoing(
        raw_hal.hal_events.clone(),
        inner_hal.out_cmd_rx,
        inner_hal.out_data_rx,
        writer,
    ));

    raw_hal
}

/// Send NCI events received from the HAL to the NCI layer
async fn dispatch_incoming<R>(
    in_cmd_tx: UnboundedSender<NciPacket>,
    in_data_tx: UnboundedSender<DataPacket>,
    mut reader: R,
) -> Result<()>
where
    R: AsyncReadExt + Unpin,
{
    loop {
        let mut buffer = BytesMut::with_capacity(1024);
        let len: usize = reader.read_u16().await?.into();
        buffer.resize(len, 0);
        reader.read_exact(&mut buffer).await?;
        let frozen = buffer.freeze();
        debug!("{:?}", &frozen);
        if is_control_packet(&frozen[..]) {
            match NciPacket::parse(&frozen) {
                Ok(p) => {
                    if in_cmd_tx.send(p).is_err() {
                        break;
                    }
                }
                Err(e) => error!("dropping invalid cmd event packet: {}: {:02x}", e, frozen),
            }
        } else {
            match DataPacket::parse(&frozen) {
                Ok(p) => {
                    if in_data_tx.send(p).is_err() {
                        break;
                    }
                }
                Err(e) => error!("dropping invalid data event packet: {}: {:02x}", e, frozen),
            }
        }
    }
    debug!("Dispatch incoming finished.");
    Ok(())
}

/// Send commands received from the NCI later to rootcanal
async fn dispatch_outgoing<W>(
    mut hal_events: HalEventRegistry,
    mut out_cmd_rx: UnboundedReceiver<NciPacket>,
    mut out_data_rx: UnboundedReceiver<DataPacket>,
    mut writer: W,
) -> Result<()>
where
    W: AsyncWriteExt + Unpin,
{
    loop {
        select! {
            Some(cmd) = out_cmd_rx.recv() => write_nci(&mut writer, cmd).await?,
            Some(data) = out_data_rx.recv() => write_nci(&mut writer, data).await?,
            else => break,
        }
    }

    writer.shutdown().await?;
    if let Some(evt) = hal_events.unregister(HalEvent::CloseComplete).await {
        evt.send(HalEventStatus::Success).unwrap();
    }
    debug!("Dispatch outgoing finished.");
    Ok(())
}

async fn write_nci<W, P>(writer: &mut W, cmd: P) -> Result<()>
where
    W: AsyncWriteExt + Unpin,
    P: Packet,
{
    let b = cmd.encode_to_bytes().unwrap();
    let mut data = BytesMut::with_capacity(b.len() + 2);
    data.put_u16(b.len().try_into().unwrap());
    data.extend(b);
    writer.write_all(&data[..]).await?;
    debug!("Sent {:?}", data);
    Ok(())
}
