extern crate coap;

use std::io::ErrorKind;
use coap::{CoAPClient, CoAPOption, CoAPRequest, CoAPResponse, CoAPServer};
use coap::IsMessage;

fn request_handler(request: CoAPRequest) -> Option<CoAPResponse> {
    let uri_path = request.get_option(CoAPOption::UriPath).unwrap();

    return match request.response {
        Some(mut response) => {
            response.set_payload(uri_path.front().unwrap().clone());
            Some(response)
        }
        _ => None,
    };
}

fn register() {
    let url = "127.0.0.1:9683";
    let endpoint = "servicediscovery/publish";

    let client = CoAPClient::new(url).unwrap();
    let mut request = CoAPRequest::new();
    request.set_code("0.02");
    request.set_version(1);

    let service_description = "
  {
    \"name\": \"crazy-827635ef\",
    \"type\": \"kalle._coap-json._udp\",
    \"host\": \"127.0.0.1\",
    \"port\": \"3400\",
    \"domain\": \"unknown\",
    \"properties\": {
      \"property\": [
        {
          \"name\": \"version\",
          \"value\": \"1.0\"
        },
        {
          \"name\": \"path\",
          \"value\": \"/palletAvailable\",
          \"loc\": \"Station-01\"
        }
      ]
    }
  }";

    request.set_payload(service_description.to_string().into_bytes());
    request.add_option(CoAPOption::UriPath, endpoint.to_string().into_bytes());
    println!("{:?}", request);

    client.send(&request).unwrap();
    println!("Client request: coap://{}{}", url, endpoint);

    match client.receive() {
        Ok(response) => {
            println!(
                "Server reply: {}",
                String::from_utf8(response.message.payload).unwrap()
            );
        }
        Err(e) => {
            match e.kind() {
                ErrorKind::WouldBlock => println!("Request timeout"), // Unix
                ErrorKind::TimedOut => println!("Request timeout"),   // Windows
                _ => println!("Request error: {:?}", e),
            }
        }
    }
}

fn main() {
    register();
    let mut server = CoAPServer::new("127.0.0.1:3400").unwrap();
    server.handle(request_handler).unwrap();
    let url = "coap://127.0.0.1:9683/servicediscovery/service/cra";
    println!("Client request: {}", url);

    let response: CoAPResponse = CoAPClient::request(url).unwrap();
    println!(
        "Server reply: {}",
        String::from_utf8(response.message.payload).unwrap()
    );
}