// Copyright 2020 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.

extern crate proc_macro;
#[macro_use]
extern crate quote;

use proc_macro2::TokenStream;
use std::fmt::Formatter;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::num::ParseIntError;
use std::str::FromStr;

/// Declares a proc_macro with `name` using `generator` to generate any of `ty`.
macro_rules! declare_macro {
    ($name:ident, $generator:ident, $($ty:ident),+) => {
        #[proc_macro]
        pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
            Emitter::<$generator, $($ty),+>::emit(input).into()
        }
    }
}

/// Empty slot in an [`Emitter`].
struct Skip;

/// The mock error returned by [`Skip`].
#[derive(Debug)]
struct SkipError;

impl std::fmt::Display for SkipError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(self, f)
    }
}
impl std::error::Error for SkipError {}

impl FromStr for Skip {
    type Err = SkipError;

    fn from_str(_s: &str) -> Result<Self, Self::Err> {
        Err(SkipError {})
    }
}

/// Generates a [`TokenStream`] representation of `T`.
trait Generator<T> {
    /// Generates the [`TokenStream`] for `input`.
    fn generate(input: T) -> TokenStream;

    /// Get an optional string representation of type `T`.
    ///
    /// Used in error reporting when parsing fails.
    fn type_str() -> Option<&'static str> {
        Some(std::any::type_name::<T>())
    }
}

impl<O> Generator<Skip> for O {
    fn generate(_input: Skip) -> TokenStream {
        unreachable!()
    }

    fn type_str() -> Option<&'static str> {
        None
    }
}

/// Attempts to emit the resulting [`TokenStream`] for `input` parsed as `T`.
fn try_emit<G, T>(input: &str) -> Result<TokenStream, T::Err>
where
    G: Generator<T>,
    T: FromStr,
{
    Ok(G::generate(T::from_str(input)?))
}

/// Provides common structor for parsing types from [`TokenStream`]s and
/// emitting the resulting [`TokenStream`].
///
/// `Emitter` can parse any of `Tn` and pass into a [`Generator`] `G`, encoding
/// the common logic for declarations build from string parsing at compile-time.
struct Emitter<G, T1 = Skip, T2 = Skip, T3 = Skip, T4 = Skip> {
    _g: std::marker::PhantomData<G>,
    _t1: std::marker::PhantomData<T1>,
    _t2: std::marker::PhantomData<T2>,
    _t3: std::marker::PhantomData<T3>,
    _t4: std::marker::PhantomData<T4>,
}

impl<G, T1, T2, T3, T4> Emitter<G, T1, T2, T3, T4>
where
    G: Generator<T1> + Generator<T2> + Generator<T3> + Generator<T4>,
    T1: FromStr,
    T2: FromStr,
    T3: FromStr,
    T4: FromStr,
    T1::Err: std::error::Error,
    T2::Err: std::error::Error,
    T3::Err: std::error::Error,
    T4::Err: std::error::Error,
{
    /// Emits the resulting [`TokenStream`] (or an error one) after attempting
    /// to parse `input` into all of the `Emitter`'s types sequentially.
    fn emit(input: proc_macro::TokenStream) -> TokenStream {
        // Always require a string literal.
        let input = proc_macro2::TokenStream::from(input);
        let s = match syn::parse2::<syn::LitStr>(input.clone()) {
            Ok(s) => s.value(),
            Err(e) => return e.to_compile_error().into(),
        };
        match try_emit::<G, T1>(&s)
            .or_else(|e1| try_emit::<G, T2>(&s).map_err(|e2| (e1, e2)))
            .or_else(|(e1, e2)| try_emit::<G, T3>(&s).map_err(|e3| (e1, e2, e3)))
            .or_else(|(e1, e2, e3)| try_emit::<G, T4>(&s).map_err(|e4| (e1, e2, e3, e4)))
        {
            Ok(ts) => ts,
            Err((e1, e2, e3, e4)) => syn::Error::new_spanned(
                input,
                format!("failed to parse as {}", Self::error_str(&e1, &e2, &e3, &e4)),
            )
            .to_compile_error()
            .into(),
        }
    }

    /// Get the error string reported to the compiler when parsing fails with
    /// this `Emitter`.
    fn error_str(
        e1: &dyn std::error::Error,
        e2: &dyn std::error::Error,
        e3: &dyn std::error::Error,
        e4: &dyn std::error::Error,
    ) -> String {
        [
            (<G as Generator<T1>>::type_str(), e1),
            (<G as Generator<T2>>::type_str(), e2),
            (<G as Generator<T3>>::type_str(), e3),
            (<G as Generator<T4>>::type_str(), e4),
        ]
        .iter()
        .filter_map(|(ts, e)| ts.map(|t| format!("{}: \"{}\"", t, e)))
        .collect::<Vec<_>>()
        .join(", or ")
    }
}

/// Generator for `std` types.
enum StdGen {}

impl Generator<IpAddr> for StdGen {
    fn generate(input: IpAddr) -> TokenStream {
        let (t, inner) = match input {
            IpAddr::V4(v4) => (quote! { V4 }, Self::generate(v4)),
            IpAddr::V6(v6) => (quote! { V6 }, Self::generate(v6)),
        };
        quote! {
            std::net::IpAddr::#t(#inner)
        }
    }
}

impl Generator<Ipv4Addr> for StdGen {
    fn generate(input: Ipv4Addr) -> TokenStream {
        let octets = input.octets();
        quote! {
            std::net::Ipv4Addr::new(#(#octets),*)
        }
    }
}

impl Generator<Ipv6Addr> for StdGen {
    fn generate(input: Ipv6Addr) -> TokenStream {
        let segments = input.segments();
        quote! {
            std::net::Ipv6Addr::new(#(#segments),*)
        }
    }
}

impl Generator<SocketAddr> for StdGen {
    fn generate(input: SocketAddr) -> TokenStream {
        let (t, inner) = match input {
            SocketAddr::V4(v4) => (quote! { V4 }, Self::generate(v4)),
            SocketAddr::V6(v6) => (quote! { V6 }, Self::generate(v6)),
        };
        quote! {
            std::net::SocketAddr::#t(#inner)
        }
    }
}

impl Generator<SocketAddrV4> for StdGen {
    fn generate(input: SocketAddrV4) -> TokenStream {
        let addr = Self::generate(input.ip().clone());
        let port = input.port();
        quote! {
            std::net::SocketAddrV4::new(#addr, #port)
        }
    }
}

impl Generator<SocketAddrV6> for StdGen {
    fn generate(input: SocketAddrV6) -> TokenStream {
        let addr = Self::generate(input.ip().clone());
        let port = input.port();
        let flowinfo = input.flowinfo();
        let scope_id = input.scope_id();
        quote! {
            std::net::SocketAddrV6::new(#addr, #port, #flowinfo, #scope_id)
        }
    }
}

declare_macro!(std_ip, StdGen, IpAddr);
declare_macro!(std_ip_v4, StdGen, Ipv4Addr);
declare_macro!(std_ip_v6, StdGen, Ipv6Addr);
declare_macro!(std_socket_addr, StdGen, SocketAddr, SocketAddrV4);
declare_macro!(std_socket_addr_v4, StdGen, SocketAddrV4);
declare_macro!(std_socket_addr_v6, StdGen, SocketAddrV6);

/// Generator for FIDL types.
enum FidlGen {}

impl Generator<IpAddr> for FidlGen {
    fn generate(input: IpAddr) -> TokenStream {
        let (t, inner) = match input {
            IpAddr::V4(v4) => (quote! { Ipv4 }, Self::generate(v4)),
            IpAddr::V6(v6) => (quote! { Ipv6 }, Self::generate(v6)),
        };
        quote! {
            fidl_fuchsia_net::IpAddress::#t(#inner)
        }
    }
}

impl Generator<Ipv4Addr> for FidlGen {
    fn generate(input: Ipv4Addr) -> TokenStream {
        let octets = input.octets();
        quote! {
            fidl_fuchsia_net::Ipv4Address{ addr: [#(#octets),*]}
        }
    }
}

impl Generator<Ipv6Addr> for FidlGen {
    fn generate(input: Ipv6Addr) -> TokenStream {
        let octets = input.octets();
        quote! {
            fidl_fuchsia_net::Ipv6Address{ addr: [#(#octets),*]}
        }
    }
}

impl Generator<SocketAddr> for FidlGen {
    fn generate(input: SocketAddr) -> TokenStream {
        let (t, inner) = match input {
            SocketAddr::V4(v4) => (quote! { Ipv4 }, Self::generate(v4)),
            SocketAddr::V6(v6) => (quote! { Ipv6 }, Self::generate(v6)),
        };
        quote! {
            fidl_fuchsia_net::SocketAddress::#t(#inner)
        }
    }
}

impl Generator<SocketAddrV4> for FidlGen {
    fn generate(input: SocketAddrV4) -> TokenStream {
        let addr = Self::generate(input.ip().clone());
        let port = input.port();
        quote! {
            fidl_fuchsia_net::Ipv4SocketAddress {
                address: #addr,
                port: #port
            }
        }
    }
}

impl Generator<SocketAddrV6> for FidlGen {
    fn generate(input: SocketAddrV6) -> TokenStream {
        let addr = Self::generate(input.ip().clone());
        let port = input.port();
        let scope_id = u64::from(input.scope_id());
        quote! {
            fidl_fuchsia_net::Ipv6SocketAddress {
                address: #addr,
                port: #port,
                zone_index: #scope_id
            }
        }
    }
}

/// Helper struct to parse Mac addresses from string.
#[derive(Default)]
struct MacAddress([u8; 6]);

#[derive(thiserror::Error, Debug)]
enum MacParseError {
    #[error("invalid length for MacAddress, should be 6")]
    InvalidLength,
    #[error("invalid byte length (\"{0}\") in MacAddress, should be 2")]
    InvalidByte(String),
    #[error("failed to parse byte \"{0}\": {1}")]
    IntError(String, ParseIntError),
}

impl FromStr for MacAddress {
    type Err = MacParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut mac = Self::default();
        let Self(octets) = &mut mac;
        let mut parse_iter = s.split(':');
        let mut save_iter = octets.iter_mut();
        loop {
            match (parse_iter.next(), save_iter.next()) {
                (Some(s), Some(b)) => {
                    if s.len() != 2 {
                        return Err(MacParseError::InvalidByte(s.to_string()));
                    }
                    *b = u8::from_str_radix(s, 16)
                        .map_err(|e| MacParseError::IntError(s.to_string(), e))?;
                }
                (None, Some(_)) | (Some(_), None) => break Err(MacParseError::InvalidLength),
                (None, None) => break Ok(mac),
            }
        }
    }
}

impl Generator<MacAddress> for FidlGen {
    fn generate(input: MacAddress) -> TokenStream {
        let MacAddress(octets) = input;
        quote! {
            fidl_fuchsia_net::MacAddress {
                octets: [#(#octets),*]
            }
        }
    }
}

/// Helper struct to parse Cidr addresses from string.
struct CidrAddress {
    address: std::net::IpAddr,
    prefix: u8,
}

#[derive(thiserror::Error, Debug)]
enum CidrParseError {
    #[error("missing address")]
    MissingIp,
    #[error("missing prefix length")]
    MissingPrefix,
    #[error("unexpected trailing data \"{0}\"")]
    TrailingInformation(String),
    #[error("failed to parse IP \"{0}\": {1}")]
    IpParseError(String, std::net::AddrParseError),
    #[error("failed to parse prefix \"{0}\": {1}")]
    PrefixParseError(String, std::num::ParseIntError),
    #[error("bad prefix value {0} for {1}")]
    BadPrefix(u8, std::net::IpAddr),
}

impl FromStr for CidrAddress {
    type Err = CidrParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut parse_iter = s.split('/');
        let ip_str = parse_iter.next().ok_or(CidrParseError::MissingIp)?;
        let prefix_str = parse_iter.next().ok_or(CidrParseError::MissingPrefix)?;
        if let Some(trailing) = parse_iter.next() {
            return Err(CidrParseError::TrailingInformation(trailing.to_string()));
        }
        let address = std::net::IpAddr::from_str(ip_str)
            .map_err(|e| CidrParseError::IpParseError(ip_str.to_string(), e))?;
        let prefix = u8::from_str_radix(prefix_str, 10)
            .map_err(|e| CidrParseError::PrefixParseError(prefix_str.to_string(), e))?;
        let addr_len = 8 * match address {
            std::net::IpAddr::V4(a) => a.octets().len(),
            std::net::IpAddr::V6(a) => a.octets().len(),
        };
        if usize::from(prefix) > addr_len {
            return Err(CidrParseError::BadPrefix(prefix, address));
        }
        Ok(CidrAddress { address, prefix })
    }
}

impl Generator<CidrAddress> for FidlGen {
    fn generate(input: CidrAddress) -> TokenStream {
        let CidrAddress { address, prefix } = input;
        let address = Self::generate(address);
        quote! {
            fidl_fuchsia_net::Subnet {
                addr: #address,
                prefix_len: #prefix
            }
        }
    }
}

declare_macro!(fidl_ip, FidlGen, IpAddr);
declare_macro!(fidl_ip_v4, FidlGen, Ipv4Addr);
declare_macro!(fidl_ip_v6, FidlGen, Ipv6Addr);
declare_macro!(fidl_socket_addr, FidlGen, SocketAddr);
declare_macro!(fidl_socket_addr_v4, FidlGen, SocketAddrV4);
declare_macro!(fidl_socket_addr_v6, FidlGen, SocketAddrV6);
declare_macro!(fidl_mac, FidlGen, MacAddress);
declare_macro!(fidl_subnet, FidlGen, CidrAddress);
