// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! # enum-as-inner
//!
//! A deriving proc-macro for generating functions to automatically give access to the inner members of enum.
//!
//! ## Basic unnamed field case
//!
//! The basic case is meant for single item enums, like:
//!
//! ```rust
//! use enum_as_inner::EnumAsInner;
//!
//! #[derive(Debug, EnumAsInner)]
//! enum OneEnum {
//!     One(u32),
//! }
//!
//! let one = OneEnum::One(1);
//!
//! assert_eq!(*one.as_one().unwrap(), 1);
//! assert_eq!(one.into_one().unwrap(), 1);
//! ```
//!
//! where the result is either a reference for inner items or a tuple containing the inner items.
//!
//! ## Unit case
//!
//! This will return true if enum's variant matches the expected type
//!
//! ```rust
//! use enum_as_inner::EnumAsInner;
//!
//! #[derive(EnumAsInner)]
//! enum UnitVariants {
//!     Zero,
//!     One,
//!     Two,
//! }
//!
//! let unit = UnitVariants::Two;
//!
//! assert!(unit.is_two());
//! ```
//!
//! ## Mutliple, unnamed field case
//!
//! This will return a tuple of the inner types:
//!
//! ```rust
//! use enum_as_inner::EnumAsInner;
//!
//! #[derive(Debug, EnumAsInner)]
//! enum ManyVariants {
//!     One(u32),
//!     Two(u32, i32),
//!     Three(bool, u32, i64),
//! }
//!
//! let many = ManyVariants::Three(true, 1, 2);
//!
//! assert!(many.is_three());
//! assert_eq!(many.as_three().unwrap(), (&true, &1_u32, &2_i64));
//! assert_eq!(many.into_three().unwrap(), (true, 1_u32, 2_i64));
//! ```
//!
//! ## Multiple, named field case
//!
//! This will return a tuple of the inner types, like the unnamed option:
//!
//! ```rust
//! use enum_as_inner::EnumAsInner;
//!
//! #[derive(Debug, EnumAsInner)]
//! enum ManyVariants {
//!     One { one: u32 },
//!     Two { one: u32, two: i32 },
//!     Three { one: bool, two: u32, three: i64 },
//! }
//!
//! let many = ManyVariants::Three { one: true, two: 1, three: 2 };
//!
//! assert!(many.is_three());
//! assert_eq!(many.as_three().unwrap(), (&true, &1_u32, &2_i64));
//! assert_eq!(many.into_three().unwrap(), (true, 1_u32, 2_i64));
//! ```

#![warn(
    clippy::default_trait_access,
    clippy::dbg_macro,
    clippy::print_stdout,
    clippy::unimplemented,
    clippy::use_self,
    missing_copy_implementations,
    missing_docs,
    non_snake_case,
    non_upper_case_globals,
    rust_2018_idioms,
    unreachable_pub
)]

use heck::ToSnakeCase;
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

/// returns first the types to return, the match names, and then tokens to the field accesses
fn unit_fields_return(variant_name: &syn::Ident, function_name: &Ident, doc: &str) -> TokenStream {
    quote!(
        #[doc = #doc]
        #[inline]
        pub fn #function_name(&self) -> bool {
            matches!(self, Self::#variant_name)
        }
    )
}

/// returns first the types to return, the match names, and then tokens to the field accesses
fn unnamed_fields_return(
    variant_name: &syn::Ident,
    (function_name_is, doc_is): (&Ident, &str),
    (function_name_mut_ref, doc_mut_ref): (&Ident, &str),
    (function_name_ref, doc_ref): (&Ident, &str),
    (function_name_val, doc_val): (&Ident, &str),
    fields: &syn::FieldsUnnamed,
) -> TokenStream {
    let (returns_mut_ref, returns_ref, returns_val, matches) = match fields.unnamed.len() {
        1 => {
            let field = fields.unnamed.first().expect("no fields on type");

            let returns = &field.ty;
            let returns_mut_ref = quote!(&mut #returns);
            let returns_ref = quote!(&#returns);
            let returns_val = quote!(#returns);
            let matches = quote!(inner);

            (returns_mut_ref, returns_ref, returns_val, matches)
        }
        0 => (quote!(()), quote!(()), quote!(()), quote!()),
        _ => {
            let mut returns_mut_ref = TokenStream::new();
            let mut returns_ref = TokenStream::new();
            let mut returns_val = TokenStream::new();
            let mut matches = TokenStream::new();

            for (i, field) in fields.unnamed.iter().enumerate() {
                let rt = &field.ty;
                let match_name = Ident::new(&format!("match_{}", i), Span::call_site());
                returns_mut_ref.extend(quote!(&mut #rt,));
                returns_ref.extend(quote!(&#rt,));
                returns_val.extend(quote!(#rt,));
                matches.extend(quote!(#match_name,));
            }

            (
                quote!((#returns_mut_ref)),
                quote!((#returns_ref)),
                quote!((#returns_val)),
                quote!(#matches),
            )
        }
    };

    quote!(
        #[doc = #doc_is ]
        #[inline]
        #[allow(unused_variables)]
        pub fn #function_name_is(&self) -> bool {
            matches!(self, Self::#variant_name(#matches))
        }

        #[doc = #doc_mut_ref ]
        #[inline]
        pub fn #function_name_mut_ref(&mut self) -> ::core::option::Option<#returns_mut_ref> {
            match self {
                Self::#variant_name(#matches) => {
                    ::core::option::Option::Some((#matches))
                }
                _ => ::core::option::Option::None
            }
        }

        #[doc = #doc_ref ]
        #[inline]
        pub fn #function_name_ref(&self) -> ::core::option::Option<#returns_ref> {
            match self {
                Self::#variant_name(#matches) => {
                    ::core::option::Option::Some((#matches))
                }
                _ => ::core::option::Option::None
            }
        }

        #[doc = #doc_val ]
        #[inline]
        pub fn #function_name_val(self) -> ::core::result::Result<#returns_val, Self> {
            match self {
                Self::#variant_name(#matches) => {
                    ::core::result::Result::Ok((#matches))
                },
                _ => ::core::result::Result::Err(self)
            }
        }
    )
}

/// returns first the types to return, the match names, and then tokens to the field accesses
fn named_fields_return(
    variant_name: &syn::Ident,
    (function_name_is, doc_is): (&Ident, &str),
    (function_name_mut_ref, doc_mut_ref): (&Ident, &str),
    (function_name_ref, doc_ref): (&Ident, &str),
    (function_name_val, doc_val): (&Ident, &str),
    fields: &syn::FieldsNamed,
) -> TokenStream {
    let (returns_mut_ref, returns_ref, returns_val, matches) = match fields.named.len() {
        1 => {
            let field = fields.named.first().expect("no fields on type");
            let match_name = field.ident.as_ref().expect("expected a named field");

            let returns = &field.ty;
            let returns_mut_ref = quote!(&mut #returns);
            let returns_ref = quote!(&#returns);
            let returns_val = quote!(#returns);
            let matches = quote!(#match_name);

            (returns_mut_ref, returns_ref, returns_val, matches)
        }
        0 => (quote!(()), quote!(()), quote!(()), quote!(())),
        _ => {
            let mut returns_mut_ref = TokenStream::new();
            let mut returns_ref = TokenStream::new();
            let mut returns_val = TokenStream::new();
            let mut matches = TokenStream::new();

            for field in fields.named.iter() {
                let rt = &field.ty;
                let match_name = field.ident.as_ref().expect("expected a named field");

                returns_mut_ref.extend(quote!(&mut #rt,));
                returns_ref.extend(quote!(&#rt,));
                returns_val.extend(quote!(#rt,));
                matches.extend(quote!(#match_name,));
            }

            (
                quote!((#returns_mut_ref)),
                quote!((#returns_ref)),
                quote!((#returns_val)),
                quote!(#matches),
            )
        }
    };

    quote!(
        #[doc = #doc_is ]
        #[inline]
        #[allow(unused_variables)]
        pub fn #function_name_is(&self) -> bool {
            matches!(self, Self::#variant_name{ #matches })
        }

        #[doc = #doc_mut_ref ]
        #[inline]
        pub fn #function_name_mut_ref(&mut self) -> ::core::option::Option<#returns_mut_ref> {
            match self {
                Self::#variant_name{ #matches } => {
                    ::core::option::Option::Some((#matches))
                }
                _ => ::core::option::Option::None
            }
        }

        #[doc = #doc_ref ]
        #[inline]
        pub fn #function_name_ref(&self) -> ::core::option::Option<#returns_ref> {
            match self {
                Self::#variant_name{ #matches } => {
                    ::core::option::Option::Some((#matches))
                }
                _ => ::core::option::Option::None
            }
        }

        #[doc = #doc_val ]
        #[inline]
        pub fn #function_name_val(self) -> ::core::result::Result<#returns_val, Self> {
            match self {
                Self::#variant_name{ #matches } => {
                    ::core::result::Result::Ok((#matches))
                }
                _ => ::core::result::Result::Err(self)
            }
        }
    )
}

fn impl_all_as_fns(ast: &DeriveInput) -> TokenStream {
    let name = &ast.ident;
    let generics = &ast.generics;

    let enum_data = if let syn::Data::Enum(data) = &ast.data {
        data
    } else {
        panic!("{} is not an enum", name);
    };

    let mut stream = TokenStream::new();

    for variant_data in &enum_data.variants {
        let variant_name = &variant_data.ident;
        let function_name_ref = Ident::new(
            &format!("as_{}", variant_name).to_snake_case(),
            Span::call_site(),
        );
        let doc_ref = format!(
            "Optionally returns references to the inner fields if this is a `{}::{}`, otherwise `None`",
            name,
            variant_name,
        );
        let function_name_mut_ref = Ident::new(
            &format!("as_{}_mut", variant_name).to_snake_case(),
            Span::call_site(),
        );
        let doc_mut_ref = format!(
            "Optionally returns mutable references to the inner fields if this is a `{}::{}`, otherwise `None`",
            name,
            variant_name,
        );

        let function_name_val = Ident::new(
            &format!("into_{}", variant_name).to_snake_case(),
            Span::call_site(),
        );
        let doc_val = format!(
            "Returns the inner fields if this is a `{}::{}`, otherwise returns back the enum in the `Err` case of the result",
            name,
            variant_name,
        );

        let function_name_is = Ident::new(
            &format!("is_{}", variant_name).to_snake_case(),
            Span::call_site(),
        );
        let doc_is = format!(
            "Returns true if this is a `{}::{}`, otherwise false",
            name, variant_name,
        );

        let tokens = match &variant_data.fields {
            syn::Fields::Unit => unit_fields_return(variant_name, &function_name_is, &doc_is),
            syn::Fields::Unnamed(unnamed) => unnamed_fields_return(
                variant_name,
                (&function_name_is, &doc_is),
                (&function_name_mut_ref, &doc_mut_ref),
                (&function_name_ref, &doc_ref),
                (&function_name_val, &doc_val),
                unnamed,
            ),
            syn::Fields::Named(named) => named_fields_return(
                variant_name,
                (&function_name_is, &doc_is),
                (&function_name_mut_ref, &doc_mut_ref),
                (&function_name_ref, &doc_ref),
                (&function_name_val, &doc_val),
                named,
            ),
        };

        stream.extend(tokens);
    }

    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

    quote!(
        impl #impl_generics #name #ty_generics #where_clause {
            #stream
        }
    )
}

/// Derive functions on an Enum for easily accessing individual items in the Enum
#[proc_macro_derive(EnumAsInner)]
pub fn enum_as_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    // get a usable token stream
    let ast: DeriveInput = parse_macro_input!(input as DeriveInput);

    // Build the impl
    let expanded: TokenStream = impl_all_as_fns(&ast);

    // Return the generated impl
    proc_macro::TokenStream::from(expanded)
}
