// 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::net_settings_types::*;

use {
    failure::{bail, Error},
    fuchsia_syslog::{fx_log_err, fx_log_info},
    rouille,
    rouille::{router, Request, Response},
    serde::de::DeserializeOwned,
    serde_json,
    std::sync::Mutex,
};

#[derive(Debug, Clone)]
struct SettingsState {
    wan_config: Option<WANConfiguration>,
    dhcp_config: Option<DHCPConfiguration>,
    ap_config: Option<APConfiguration>,
}

impl Default for SettingsState {
    fn default() -> SettingsState {
        SettingsState {
            wan_config: Some(WANConfiguration {
                addr: NetAddress::V4([0, 0, 0, 0], 32),
                dynamically_assigned: false,
            }),
            // TODO(NET-1429): Secure defaults for this.
            dhcp_config: Some(DHCPConfiguration {
                dns_server_addr: NetAddress::V4([8, 8, 8, 8], 32),
                netmask: NetAddress::V4([192, 168, 41, 0], 24),
                addr_range: (
                    NetAddress::V4([192, 168, 41, 1], 32),
                    NetAddress::V4([192, 168, 41, 255], 32),
                ),
            }),
            // TODO(NET-1429): Secure defaults for this.
            ap_config: Some(APConfiguration {
                ssid: String::from("Basking Rootwalla").into_bytes(),
                password: String::from(""),
            }),
        }
    }
}

struct SettingsServer {
    page: String,
    current_settings: SettingsState,
}

impl SettingsServer {
    fn new(frontend_webpage: String) -> SettingsServer {
        SettingsServer {
            page: frontend_webpage,
            current_settings: SettingsState::default(),
        }
    }

    // TODO(NET-1430): Hook up to wlancfg FIDL endpoints.
    fn set_wan_config(&mut self, config: WANConfiguration) {
        self.current_settings.wan_config = Some(config);
    }

    fn get_wan_config(&self) -> Option<WANConfiguration> {
        self.current_settings.wan_config.as_ref().cloned()
    }

    // TODO(NET-1430): Hook up to netcfg FIDL endpoints.
    fn set_dhcp_config(&mut self, config: DHCPConfiguration) {
        self.current_settings.dhcp_config = Some(config);
    }

    fn get_dhcp_config(&self) -> Option<DHCPConfiguration> {
        self.current_settings.dhcp_config.as_ref().cloned()
    }

    // TODO(NET-1430): Hook up to wlancfg FIDL endpoints.
    fn set_ap_config(&mut self, config: APConfiguration) {
        self.current_settings.ap_config = Some(config);
    }

    fn get_ap_config(&self) -> Option<APConfiguration> {
        self.current_settings.ap_config.as_ref().cloned()
    }
}

pub fn start_server(address: String, webpage: String) -> ! {
    let server = Mutex::new(SettingsServer::new(webpage));
    rouille::start_server(&address[..], move |request| {
        let mut settings = &mut server.lock().unwrap();
        handle_client_request(&mut settings, request)
    });
}

fn parse_request<T: DeserializeOwned>(request: &Request) -> Result<T, Error> {
    let data = match request.data() {
        Some(d) => d,
        None => bail!("Failed to parse request: no data"),
    };

    Ok(serde_json::from_reader(data)?)
}

fn success() -> Response {
    Response::text("") // Empty success
}

fn handle_client_request(server: &mut SettingsServer, request: &Request) -> Response {
    router!(request,
        (GET) (/) => {
            fx_log_info!(tag: "server", "Received GET for index page.");
            Response::html(server.page.clone())
        },
        (GET) (/wan_info) => {
            fx_log_info!(tag: "server", "Received GET for wan_info.");

            match serde_json::to_string(&server.get_wan_config()) {
                Ok(data) => {
                    Response::from_data("application/json", data.into_bytes())
                },
                Err(e) => {
                    fx_log_err!(tag: "server", "Couldn't create response! Error: {}", e);
                    Response::text("").with_status_code(500)
                },
            }
        },
        (PUT) (/wan_info) => {
            fx_log_info!(tag: "server", "Received PUT for wan_info.");

            let wan_info = match parse_request(request) {
                Ok(info) => info,
                Err(e) => {
                    fx_log_err!(tag: "server", "Bad Request: {}", e);
                    return Response::empty_400();
                },
            };

            server.set_wan_config(wan_info);
            success()
        },
        (GET) (/ssid_info) => {
            fx_log_info!(tag: "server", "Received GET for ssid_info.");
            match serde_json::to_string(&server.get_ap_config()) {
                Ok(data) => {
                    Response::from_data("application/json", data.into_bytes())
                },
                Err(e) => {
                    fx_log_err!(tag: "server", "Couldn't create response! Error: {}", e);
                    Response::text("").with_status_code(500)
                },
            }
        },
        (PUT) (/ssid_info) => {
            fx_log_info!(tag: "server", "Received PUT for ssid_info.");
            let ssid_info = match parse_request(request) {
                Ok(info) => info,
                Err(e) => {
                    fx_log_err!(tag: "server", "Bad Request: {}", e);
                    return Response::empty_400();
                },
            };

            server.set_ap_config(ssid_info);
            success()
        },
        (GET) (/dhcp_info) => {
            fx_log_info!(tag: "server", "Received GET for dhcp_info.");
            match serde_json::to_string(&server.get_dhcp_config()) {
                Ok(data) => {
                    Response::from_data("application/json", data.into_bytes())
                },
                Err(e) => {
                    fx_log_err!(tag: "server", "Couldn't create response! Error: {}", e);
                    Response::text("").with_status_code(500)
                },
            }
        },
        (PUT) (/dhcp_info) => {
            fx_log_info!(tag: "server", "Received PUT for dhcp_info.");
            let dhcp_info = match parse_request(request) {
                Ok(info) => info,
                Err(e) => {
                    fx_log_err!(tag: "server", "Bad Request: {}", e);
                    return Response::empty_400();
                },
            };

            server.set_dhcp_config(dhcp_info);
            success()
        },
        _ => {
            fx_log_err!(tag: "server", "Received unknown request.");
            Response::empty_404()
        }
    )
}
