use rs_transfer::{endpoint::FileEndpoint, list::TreeList};

fn get_path_in_current_dir(path: &str) -> String {
  let current_dir = std::env::current_dir().unwrap();
  let root_path = current_dir.join(path);
  root_path.to_str().unwrap().to_string()
}

#[async_std::test]
pub async fn test_file_tree_list_tree() {
  let root_path = get_path_in_current_dir("src/");

  let file_tree = FileEndpoint::default();

  let result = file_tree.list_tree(&root_path, None).await;

  assert!(result.is_ok());

  let entries = result.unwrap();

  let expected_root_path = get_path_in_current_dir("src");

  {
    let expected_file_path = format!("{expected_root_path}/lib.rs");
    let expected_relative_path = expected_file_path
      .strip_prefix(&expected_root_path)
      .unwrap();

    let item = entries
      .iter()
      .inspect(|entry| println!("path: {}", entry.path()))
      .find(|entry| entry.path() == expected_file_path)
      .unwrap();

    assert_eq!(item.root_path(), expected_root_path);
    assert_eq!(item.relative_path(), expected_relative_path);
  }

  {
    let expected_file_path = format!("{root_path}endpoint/mod.rs");
    let expected_relative_path = expected_file_path
      .strip_prefix(&expected_root_path)
      .unwrap();

    let item = entries
      .iter()
      .find(|entry| entry.path() == expected_file_path)
      .unwrap();

    assert_eq!(item.root_path(), expected_root_path);
    assert_eq!(item.relative_path(), expected_relative_path);
  }
}

#[async_std::test]
pub async fn test_file_tree_list() {
  let root_path = get_path_in_current_dir("src");
  let file_tree = FileEndpoint::default();

  let result = file_tree.list(&root_path, None).await;

  assert!(result.is_ok());

  let entries = result.unwrap();

  let expected_root_path = &root_path;

  {
    let expected_file_path = format!("{root_path}/lib.rs");
    let expected_relative_path = expected_file_path.strip_prefix(expected_root_path).unwrap();

    let item = entries
      .iter()
      .find(|entry| entry.path() == expected_file_path)
      .unwrap();

    assert_eq!(item.root_path(), expected_root_path);
    assert_eq!(item.relative_path(), expected_relative_path);
  }

  {
    let expected_file_path = format!("{root_path}/endpoint");
    let expected_relative_path = expected_file_path.strip_prefix(expected_root_path).unwrap();

    let item = entries
      .iter()
      .find(|entry| entry.path() == expected_file_path)
      .unwrap();

    assert_eq!(item.root_path(), expected_root_path);
    assert_eq!(item.relative_path(), expected_relative_path);
  }

  {
    let unexpected_file_path = format!("{root_path}/endpoint/mod.rs");
    assert!(
      !entries
        .iter()
        .any(|entry| entry.path() == unexpected_file_path)
    );
  }
}

#[async_std::test]
pub async fn test_file_tree_invalid_list() {
  let file_path = get_path_in_current_dir("Cargo.toml");

  let file_tree = FileEndpoint::default();

  let items = file_tree.list(&file_path, None).await.unwrap();
  assert!(items.is_empty());
}
