use clap::Parser;
use log::LevelFilter;
use rs_transfer::{endpoint::SftpEndpoint, list::TreeList, secret::SftpSecret};
use std::convert::TryFrom;

#[derive(Parser, Debug)]
struct Args {
  #[clap(short = 'H', long)]
  hostname: String,
  #[clap(short = 'P', long)]
  port: Option<u16>,
  #[clap(short, long)]
  username: String,
  #[clap(
    short,
    long,
    conflicts_with = "private_key",
    conflicts_with = "private_key_file_path"
  )]
  password: Option<String>,
  #[clap(
    short,
    long,
    conflicts_with = "password",
    conflicts_with = "private_key_file_path"
  )]
  private_key: Option<String>,
  #[clap(
    short,
    long,
    conflicts_with = "password",
    conflicts_with = "private_key"
  )]
  private_key_file_path: Option<String>,
  #[clap(short, long)]
  known_host: Option<String>,
  #[clap(short, long, default_value = "/")]
  root_path: String,
  #[clap(long)]
  prefix: Option<String>,
}

#[async_std::main]
async fn main() {
  env_logger::builder().filter_level(LevelFilter::Info).init();

  let args = Args::parse();

  let secret = SftpSecret {
    hostname: args.hostname,
    port: args.port,
    username: args.username,
    password: args.password.map(|value| value.into()),
    private_key: args.private_key.map(|value| value.into()),
    private_key_file_path: args.private_key_file_path.map(|value| value.into()),
    known_host: args.known_host.map(|value| value.into()),
    root_directory: Some(args.root_path.clone()),
  };

  let sftp_tree = SftpEndpoint::try_from(&secret).unwrap();
  let root_path = args.root_path;
  let prefix = args.prefix.as_deref();

  println!("\n### List: root_path={root_path}, prefix={prefix:?}");
  {
    let items = sftp_tree.list(&root_path, prefix).await.unwrap();
    for item in items {
      println!(" - {item:?}");
    }
  }

  println!("\n### List tree: root_path={root_path}, prefix={prefix:?}");
  {
    let items = sftp_tree.list_tree(&root_path, prefix).await.unwrap();
    for item in items {
      println!(" - {item:?}");
    }
  }
}
