// Copyright 2019 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 {
    anyhow::{format_err, Context as _, Error},
    argh::FromArgs,
    fidl_fuchsia_net_stack::StackMarker,
    fidl_fuchsia_netemul_sync::{BusMarker, BusProxy, SyncManagerMarker},
    fuchsia_async as fasync,
    fuchsia_component::client,
    std::io::{Read, Write},
    std::net::{SocketAddr, TcpListener, TcpStream},
};

const BUS_NAME: &str = "test-bus";
const SERVER_NAME: &str = "server";
const CLIENT_NAME: &str = "client";
const HELLO_MSG_REQ: &str = "Hello World from Client!";
const HELLO_MSG_RSP: &str = "Hello World from Server!";
const SERVER_IPS: [&str; 2] = ["192.168.0.1", "192.168.0.3"];
const PORT: i32 = 8080;

pub struct BusConnection {
    bus: BusProxy,
}

impl BusConnection {
    pub fn new(client: &str) -> Result<BusConnection, Error> {
        let busm = client::connect_to_service::<SyncManagerMarker>()
            .context("SyncManager not available")?;
        let (bus, busch) = fidl::endpoints::create_proxy::<BusMarker>()?;
        busm.bus_subscribe(BUS_NAME, client, busch)?;
        Ok(BusConnection { bus })
    }

    pub async fn wait_for_client(&mut self, expect: &'static str) -> Result<(), Error> {
        let _ = self.bus.wait_for_clients(&mut vec![expect].drain(..), 0).await?;
        Ok(())
    }
}

async fn run_server() -> Result<(), Error> {
    let listeners = SERVER_IPS
        .iter()
        .map(|ip| {
            TcpListener::bind(&format!("{}:{}", ip, PORT))
                .with_context(|| format!("can't bind to address {}", ip))
        })
        .collect::<Result<Vec<_>, _>>()?;
    log::info!("Waiting for connections...");

    let _bus = BusConnection::new(SERVER_NAME)?;

    for listener in listeners {
        let (mut stream, remote) = listener.accept().context("Accept failed")?;
        log::info!("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));
        }
        log::info!("Got request {}", req);
        stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?;
        stream.flush().context("flush failed")?;
    }

    Ok(())
}

async fn run_client(gateway: Option<String>) -> Result<(), Error> {
    if let Some(gateway) = gateway {
        let gw_addr: fidl_fuchsia_net::IpAddress = fidl_fuchsia_net_ext::IpAddress(
            gateway.parse::<std::net::IpAddr>().context("failed to parse gateway address")?,
        )
        .into();
        test_gateway(gw_addr).await.context("test_gateway failed")?;
    }

    log::info!("Waiting for server...");
    let mut bus = BusConnection::new(CLIENT_NAME)?;
    let () = bus.wait_for_client(SERVER_NAME).await?;

    for ip in SERVER_IPS.iter() {
        log::info!("Connecting to server at IP address {}...", ip);
        let addr: SocketAddr = format!("{}:{}", ip, PORT).parse()?;
        let mut stream = TcpStream::connect(&addr).context("Tcp connection failed")?;
        let request = HELLO_MSG_REQ.as_bytes();
        stream.write(request)?;
        stream.flush()?;

        let mut buffer = [0; 512];
        let rd = stream.read(&mut buffer)?;
        let rsp = String::from_utf8_lossy(&buffer[0..rd]);
        log::info!("Got response {}", rsp);
        if rsp != HELLO_MSG_RSP {
            return Err(format_err!("Got unexpected echo from server: {}", rsp));
        }
    }

    Ok(())
}

async fn test_gateway(gw_addr: fidl_fuchsia_net::IpAddress) -> Result<(), Error> {
    let stack =
        client::connect_to_service::<StackMarker>().context("failed to connect to netstack")?;
    let response =
        stack.get_forwarding_table().await.context("failed to call get_forwarding_table")?;
    let found = response.iter().any(|entry| {
        let fidl_fuchsia_net_ext::IpAddress(entry_addr) = entry.subnet.addr.into();
        if let fidl_fuchsia_net_stack::ForwardingDestination::NextHop(gw) = entry.destination {
            entry_addr.is_unspecified() && entry.subnet.prefix_len == 0 && gw == gw_addr
        } else {
            false
        }
    });
    if found {
        log::info!("Found default route for gateway");
        Ok(())
    } else {
        let fidl_fuchsia_net_ext::IpAddress(gw) = gw_addr.into();
        let unspecified = match gw {
            std::net::IpAddr::V4(_) => std::net::IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED),
            std::net::IpAddr::V6(_) => std::net::IpAddr::V6(std::net::Ipv6Addr::UNSPECIFIED),
        };
        Err(format_err!("could not find {}/0 next hop {} in {:?}", unspecified, gw, response))
    }
}

#[derive(FromArgs, Debug)]
/// Easy netstack configuration test.
struct Opt {
    /// whether the test is run as a child
    #[argh(switch, short = 'c')]
    is_child: bool,
    /// an optional gateway to test
    #[argh(option, short = 'g')]
    gateway: Option<String>,
}

fn main() -> Result<(), Error> {
    let () = fuchsia_syslog::init().context("cannot init logger")?;

    let opt: Opt = argh::from_env();
    let mut executor = fasync::Executor::new().context("Error creating executor")?;
    executor.run_singlethreaded(async {
        if opt.is_child {
            run_client(opt.gateway).await
        } else {
            run_server().await
        }
    })
}
