use rand::{thread_rng, Rng};
use std::sync::Arc;
use tapir_cwtch::acns::tor::run::TorRunner;
use tapir_cwtch::acns::tor::torrc::TorrcGenerator;
use tapir_cwtch::applications::authentication_app::{AuthenicationApp, AUTHENTICATION_CAPABILITY};
use tapir_cwtch::connections::service::Service;
use tapir_cwtch::connections::{Connection, ConnectionInterface, OutboundConnection};
use tapir_cwtch::primitives::identity::Identity;
use tapir_cwtch::primitives::transcript::Transcript;

fn main() {
    let identity = Arc::new(Identity::initialize_ephemeral_identity());
    println!("Setup: {}", identity.hostname());

    let tor_path = which::which("tor");
    let mut rng = thread_rng();
    let socks_port = rng.gen_range(9052, 9100);
    let mut tor_runner = TorRunner::run(
        TorrcGenerator::new().with_socks_port(socks_port),
        "./example_client_rc",
        tor_path.unwrap().to_str().unwrap(),
        "./examples/client_data_dir/",
    )
    .unwrap();
    tor_runner.wait_until_bootstrapped();

    let mut service = Service::init(identity.clone(), socks_port);
    let identity = identity.clone();
    let outbound_identity = identity.clone();
    let outbound_service = |conn: Connection<OutboundConnection>| {
        let mut transcript = Transcript::new_transcript("tapir-transcript");
        let mut auth_app = AuthenicationApp::new(outbound_identity);
        match auth_app.run_outbound(conn, &mut transcript) {
            Ok(conn) => {
                println!("Authenticated {} {}", conn.hostname(), conn.has_capability(&AUTHENTICATION_CAPABILITY));
            }
            Err(err) => {
                println!("Error: {:?}", err);
            }
        }
    };
    match service.connect("srg3w256xrpcs6o25i5qlo6iviwsybnfw66nwelrbah7c5e6knb32xyd", outbound_service.clone()) {
        _ => {}
    }
    loop {}
}
