use std::{path::Path, ptr};

use thiserror::Error;

use aos_configuration_fbs::aos::{Channel as RustChannel, Configuration as RustConfiguration};
use aos_flatbuffers::{transmute_table_to, NonSizePrefixedFlatbuffer};

autocxx::include_cpp! (
#include "aos/configuration.h"
#include "aos/configuration_for_rust.h"
#include "aos/configuration_generated.h"

safety!(unsafe)

generate!("aos::Configuration")
generate!("aos::Channel")
generate!("aos::Node")
block!("flatbuffers::String")
block!("flatbuffers::Verifier")

generate!("aos::configuration::GetChannelForRust")
generate!("aos::configuration::GetNodeForRust")

generate!("aos::configuration::HasChannelTypeForRust")
generate!("aos::configuration::GetChannelTypeForRust")
generate!("aos::configuration::HasChannelNameForRust")
generate!("aos::configuration::GetChannelNameForRust")
);

#[cxx::bridge]
mod ffi2 {
    #[namespace = "aos::configuration"]
    unsafe extern "C++" {
        include!("aos/configuration_for_rust.h");
        fn MaybeReadConfigForRust(path: &str, extra_import_paths: &[&str]) -> Vec<u8>;
    }
}

pub use ffi::aos::{Channel, Configuration, Node};

#[derive(Clone, Copy, Eq, PartialEq, Debug, Error)]
pub enum ChannelLookupError {
    #[error("channel not found")]
    NotFound,
}

#[derive(Clone, Copy, Eq, PartialEq, Debug, Error)]
pub enum NodeLookupError {
    #[error("node not found")]
    NotFound,
}

#[derive(Clone, Copy, Eq, PartialEq, Debug, Error)]
pub enum ReadConfigError {
    #[error("duplicate imports or invalid paths")]
    ReadFailed,
}

impl<'a> Into<&'a Configuration> for RustConfiguration<'a> {
    fn into(self) -> &'a Configuration {
        unsafe { transmute_table_to(&self._tab) }
    }
}

/// A trait with useful helper methods for a `Configuration` table. Import this trait to get these
/// methods on both the `Configuration` struct generated by autocxx from the C++ code generated by
/// flatbuffers, and the `Configuration` struct generated by flatbuffers in Rust.
pub trait ConfigurationExt<'a>: Into<&'a Configuration> {
    fn get_channel(
        self,
        name: &str,
        typename: &str,
        application_name: &str,
        node: Option<&Node>,
    ) -> Result<&'a Channel, ChannelLookupError> {
        // SAFETY: All the input references are valid pointers, and we're not doing anything with
        // the result yet. It doesn't store any of the input references.
        let channel = unsafe {
            ffi::aos::configuration::GetChannelForRust(
                self.into(),
                name,
                typename,
                application_name,
                node.map_or(ptr::null(), |p| p),
            )
        };
        if channel.is_null() {
            Err(ChannelLookupError::NotFound)
        } else {
            // SAFETY: We know this is a valid pointer now, and we're returning it with the lifetime
            // inherited from `self` which owns it.
            Ok(unsafe { &*channel })
        }
    }

    fn get_node(self, name: &str) -> Result<&'a Node, NodeLookupError> {
        // SAFETY: All the input references are valid pointers, and we're not doing anything with
        // the result yet. It doesn't store any of the input references.
        let node = unsafe { ffi::aos::configuration::GetNodeForRust(self.into(), name) };
        if node.is_null() {
            Err(NodeLookupError::NotFound)
        } else {
            // SAFETY: We know this is a valid pointer now, and we're returning it with the lifetime
            // inherited from `self` which owns it.
            Ok(unsafe { &*node })
        }
    }
}

impl<'a, T: Into<&'a Configuration>> ConfigurationExt<'a> for T {}

impl<'a> Into<&'a Channel> for RustChannel<'a> {
    fn into(self) -> &'a Channel {
        unsafe { transmute_table_to(&self._tab) }
    }
}

pub trait ChannelExt<'a>: Into<&'a Channel> {
    fn type_(self) -> Option<&'a str> {
        let c = self.into();
        ffi::aos::configuration::HasChannelTypeForRust(c)
            .then(move || ffi::aos::configuration::GetChannelTypeForRust(c))
    }

    fn name(self) -> Option<&'a str> {
        let c = self.into();
        ffi::aos::configuration::HasChannelNameForRust(c)
            .then(move || ffi::aos::configuration::GetChannelNameForRust(c))
    }
}

impl<'a, T: Into<&'a Channel>> ChannelExt<'a> for T {}

/// # Panics
///
/// `path` must be valid UTF-8.
pub fn read_config_from(
    path: &Path,
) -> Result<NonSizePrefixedFlatbuffer<RustConfiguration<'static>, Vec<u8>>, ReadConfigError> {
    read_config_from_import_paths(path, &[])
}

/// # Panics
///
/// `path` and all members of `extra_import_paths` must be valid UTF-8.
pub fn read_config_from_import_paths(
    path: &Path,
    extra_import_paths: &[&Path],
) -> Result<NonSizePrefixedFlatbuffer<RustConfiguration<'static>, Vec<u8>>, ReadConfigError> {
    let extra_import_paths: Vec<_> = extra_import_paths
        .iter()
        .map(|p| p.to_str().expect("Paths must be UTF-8"))
        .collect();
    let buffer = ffi2::MaybeReadConfigForRust(
        path.to_str().expect("Paths must be UTF-8"),
        &extra_import_paths,
    );
    if buffer.is_empty() {
        return Err(ReadConfigError::ReadFailed);
    }
    // SAFETY: The C++ code returns a valid flatbuffer (unless it returned an error, which we
    // checked above).
    return Ok(unsafe { NonSizePrefixedFlatbuffer::new_unchecked(buffer) });
}

#[cfg(test)]
mod tests {
    use super::*;

    use aos_flatbuffers::Flatbuffer;

    #[test]
    fn read_config() {
        let config = read_config_from(Path::new("aos/testdata/config1.json")).unwrap();
        assert!(
            config
                .message()
                .channels()
                .unwrap()
                .iter()
                .find(|channel| channel.type_() == Some(".aos.bar"))
                .is_some(),
            "Failed to find the .aos.bar channel: {:?}",
            config.message()
        );
    }
}
