// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::common::{BusConnection, SERVER_READY},
    anyhow::{format_err, Context as _, Error},
    fidl_fuchsia_net,
    fidl_fuchsia_netemul_network::{DeviceConnection, EndpointManagerMarker, NetworkContextMarker},
    fidl_fuchsia_netstack::{InterfaceConfig, NetstackMarker},
    fuchsia_component::client,
    std::io::{Read, Write},
    std::net::{SocketAddr, TcpListener, TcpStream},
    std::str::FromStr,
};

const PORT: i32 = 8080;
const HELLO_MSG_REQ: &str = "Hello World from Client!";
const HELLO_MSG_RSP: &str = "Hello World from Server!";
const DEFAULT_METRIC: u32 = 100;

pub struct ChildOptions {
    pub endpoint: String,
    pub ip: String,
    pub connect_ip: Option<String>,
}

fn publish_server_ready() -> Result<(), Error> {
    let bc = BusConnection::new("server")?;
    bc.publish_code(SERVER_READY)
}

fn run_server(ip: &str) -> Result<(), Error> {
    let addr = format!("{}:{}", ip, PORT);
    let listener = TcpListener::bind(&addr).context(format!("Can't bind to address: {}", addr))?;
    println!("Waiting for connections...");
    let () = publish_server_ready()?;
    let (mut stream, remote) = listener.accept().context("Accept failed")?;
    println!("Accepted connection from {}", remote);
    let mut buffer = [0; 512];
    let rd = stream.read(&mut buffer).context("read failed")?;

    let req = String::from_utf8_lossy(&buffer[0..rd]);
    if req != HELLO_MSG_REQ {
        return Err(format_err!("Got unexpected request from client: '{}'", req));
    }
    println!("Got request ({} bytes) '{}'", rd, req);
    println!("Sending response '{}'", HELLO_MSG_RSP);
    assert_eq!(
        stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?,
        HELLO_MSG_RSP.as_bytes().len()
    );
    stream.flush().context("flush failed")?;
    println!("Server done");
    Ok(())
}

fn run_client(server_ip: &str) -> Result<(), Error> {
    println!("Connecting to server...");
    let addr = SocketAddr::from_str(&format!("{}:{}", server_ip, PORT))?;
    let mut stream = TcpStream::connect(&addr).context("Tcp connection failed")?;
    println!("Connected to server!");
    let request = HELLO_MSG_REQ.as_bytes();
    println!("Sending message '{}'", HELLO_MSG_REQ);
    assert_eq!(stream.write(request).context("write failed")?, request.len());
    stream.flush().context("flush failed")?;

    let mut buffer = [0; 512];
    println!("Waiting for server response...");
    let rd = stream.read(&mut buffer)?;
    let rsp = String::from_utf8_lossy(&buffer[0..rd]);
    println!("Got response ({} bytes) '{}'", rd, rsp);
    if rsp != HELLO_MSG_RSP {
        return Err(format_err!("Got unexpected echo from server: '{}'", rsp));
    }
    println!("Client done");
    Ok(())
}

pub async fn run_child(opt: ChildOptions) -> Result<(), Error> {
    println!("Running child with endpoint '{}'", opt.endpoint);

    // get the network context service:
    let netctx = client::connect_to_service::<NetworkContextMarker>()?;
    // get the endpoint manager
    let (epm, epmch) = fidl::endpoints::create_proxy::<EndpointManagerMarker>()?;
    netctx.get_endpoint_manager(epmch)?;

    // retrieve the created endpoint:
    let ep = epm.get_endpoint(&opt.endpoint).await?;
    let ep = ep.ok_or_else(|| format_err!("can't find endpoint {}", opt.endpoint))?.into_proxy()?;
    // and the device connection:
    let device_connection = ep.get_device().await?;

    let if_name = format!("eth-{}", opt.endpoint);
    // connect to netstack:
    let netstack = client::connect_to_service::<NetstackMarker>()?;
    let static_ip =
        opt.ip.parse::<fidl_fuchsia_net_ext::Subnet>().expect("must be able to parse ip");
    println!("static ip = {:?}", static_ip);

    let use_ip = match opt.ip.split("/").next() {
        Some(v) => String::from(v),
        None => opt.ip,
    };

    let mut cfg = InterfaceConfig {
        name: if_name.to_string(),
        filepath: "[TBD]".to_string(),
        metric: DEFAULT_METRIC,
    };
    let nicid = match device_connection {
        DeviceConnection::Ethernet(eth) => netstack
            .add_ethernet_device(&format!("/vdev/{}", opt.endpoint), &mut cfg, eth)
            .await
            .context("add_ethernet_device FIDL error")?
            .map_err(fuchsia_zircon::Status::from_raw)
            .context("add_ethernet_device error")?,
        DeviceConnection::NetworkDevice(netdevice) => {
            todo!("(48860) Support and test NetworkDevice connections. Got unexpected NetworkDevice {:?}", netdevice);
        }
    };

    let () = netstack.set_interface_status(nicid as u32, true)?;
    let fidl_fuchsia_net::Subnet { mut addr, prefix_len } = static_ip.clone().into();
    let _ = netstack.set_interface_address(nicid as u32, &mut addr, prefix_len).await?;

    let interface_state = client::connect_to_service::<fidl_fuchsia_net_interfaces::StateMarker>()?;
    let () = fidl_fuchsia_net_interfaces_ext::wait_interface_with_id(
        fidl_fuchsia_net_interfaces_ext::event_stream_from_state(&interface_state)?,
        &mut fidl_fuchsia_net_interfaces_ext::InterfaceState::Unknown(nicid.into()),
        |&fidl_fuchsia_net_interfaces_ext::Properties { online, .. }| {
            // TODO(https://github.com/rust-lang/rust/issues/80967): use bool::then_some.
            online.then(|| ())
        },
    )
    .await
    .context("wait for interface online")?;

    println!("Found ethernet with id {}", nicid);

    if let Some(remote) = opt.connect_ip {
        run_client(&remote)
    } else {
        run_server(&use_ip)
    }
}
