use async_std::channel::unbounded;
use rs_transfer::{
  StreamData,
  endpoint::FileEndpoint,
  reader::{SimpleReader, StreamReader},
  writer::{DummyWriteJob, StreamWriter},
};

#[tokio::test]
pub async fn test_file_reader() {
  let file_path = "./README.md";

  let file_content = std::fs::read(file_path).unwrap();
  let file_size = file_content.len() as u64;

  let (sender, receiver) = unbounded::<StreamData>();
  let file_reader = FileEndpoint::default();
  let simple_reader = SimpleReader {};

  let read_data = file_reader
    .read_stream(file_path, sender, &simple_reader)
    .await
    .unwrap();

  let mut read_content = vec![];
  loop {
    let received = receiver.recv().await.unwrap();
    match received {
      StreamData::Data(data) => read_content.extend(data),
      StreamData::Size(expected_size) => assert_eq!(expected_size, file_size),
      StreamData::Stop => break,
      StreamData::Eof => break,
    }
  }

  assert_eq!(read_data, file_size);
  assert_eq!(read_content, file_content);
}

#[tokio::test]
pub async fn test_file_writer() {
  let root_path = ".";
  let file_path = "tests/tmp.txt";

  let content = r#"Logoden biniou degemer mat an penn ar, bed Kastell-Paol Sant-Nouga lien dimeurzh.
Pevarzek huñvre digant kazh kleñved, etrezek tu Rosko anezho, e kregiñ stur. Kazetenn Liger kilhog Kernev
kerf Roazhon amzer, hepken erc’h pevar bleunioù ganit. Ouzhimp kousket egistout wechoù gwech broust grizilh,
ur sellout Pask vazh voutailh. Hervez  e eget puñs sec’h askell Tregastell, doug genou sadorn Ar Gall Rosko.
C’harrez sec’hañ itron naon leal roll c’henwerzh, hepken gwenodenn gar hi Skrigneg. Speredek vazh plij
liorzh stank gouren gwerzhañ, bodañ c’hroaz derc’hent gouest skiant. C’hoari glebiañ bodet vouezh Perros-Gireg,
harzoù dañvad soudard logod, c’hwezek deiz kemmañ. Diskenn gounez park poan fiziañs, c’hardeur koumanant
Skos endervezh, degas seiz kelc’hiek. Lonkañ gwin ac’hano bihan ur, dibab re kenwerzh vrec’h, sav kalonek koulz.
"#;
  let content_data = content.as_bytes();
  let content_size = content_data.len() as u64;

  let (sender, receiver) = unbounded::<StreamData>();
  let file_writer = FileEndpoint::default();
  let simple_writer = DummyWriteJob {};

  sender.send(StreamData::Size(content_size)).await.unwrap();
  for chunk in content_data.chunks(100) {
    sender.send(StreamData::Data(chunk.to_vec())).await.unwrap();
  }

  sender.send(StreamData::Eof).await.unwrap();

  file_writer
    .write_stream(file_path, receiver, &simple_writer)
    .await
    .unwrap();

  let output_file_path = format!("{root_path}/{file_path}");
  let file_content = std::fs::read(&output_file_path).unwrap();
  let file_size = file_content.len() as u64;

  std::fs::remove_file(output_file_path).unwrap();

  assert_eq!(content_size, file_size);
  assert_eq!(content_data, file_content);
}
