// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

use proc_macro::TokenStream;
use proc_macro2::Ident;
use quote::quote;
use syn::{
    parse::{Parse, ParseStream},
    parse_macro_input, Expr, Token,
};

use pw_format::macros::{
    generate_core_fmt, Arg, CoreFmtFormatMacroGenerator, CoreFmtFormatStringParser,
    FormatAndArgsFlavor, FormatStringParser, PrintfFormatStringParser, Result,
};

type TokenStream2 = proc_macro2::TokenStream;

// Arguments to `pw_log[f]_backend`.  A log level followed by a [`pw_format`]
// format string.
#[derive(Debug)]
struct PwLogArgs<T: FormatStringParser> {
    log_level: Expr,
    format_and_args: FormatAndArgsFlavor<T>,
}

impl<T: FormatStringParser> Parse for PwLogArgs<T> {
    fn parse(input: ParseStream) -> syn::parse::Result<Self> {
        let log_level: Expr = input.parse()?;
        input.parse::<Token![,]>()?;
        let format_and_args: FormatAndArgsFlavor<_> = input.parse()?;

        Ok(PwLogArgs {
            log_level,
            format_and_args,
        })
    }
}

// Generator that implements [`pw_format::CoreFmtFormatMacroGenerator`] to take
// a log line output it through the system console.
struct LogfGenerator<'a> {
    log_level: &'a Expr,
    args: Vec<TokenStream2>,
}

impl<'a> LogfGenerator<'a> {
    fn new(log_level: &'a Expr) -> Self {
        Self {
            log_level,
            args: Vec::new(),
        }
    }
}

impl CoreFmtFormatMacroGenerator for LogfGenerator<'_> {
    fn finalize(self, format_string: String) -> Result<TokenStream2> {
        let log_level = self.log_level;
        let args = &self.args;
        let format_string = format!("[{{}}] {format_string}\n");
        Ok(quote! {
          {
            use __pw_log_backend_crate::embedded_io::Write;
            let mut console = __pw_log_backend_crate::console::get_console();
            let _ = core::write!(
                &mut console,
                #format_string,
                __pw_log_backend_crate::log_level_tag(#log_level),
                #(#args),*
            );
          }
        })
    }

    fn string_fragment(&mut self, _string: &str) -> Result<()> {
        // String fragments are encoded directly into the format string.
        Ok(())
    }

    fn integer_conversion(&mut self, ty: Ident, expression: Arg) -> Result<Option<String>> {
        self.args.push(quote! {((#expression) as #ty)});
        Ok(None)
    }

    fn string_conversion(&mut self, expression: Arg) -> Result<Option<String>> {
        self.args.push(quote! {((#expression) as &str)});
        Ok(None)
    }

    fn char_conversion(&mut self, expression: Arg) -> Result<Option<String>> {
        self.args.push(quote! {((#expression) as char)});
        Ok(None)
    }

    fn untyped_conversion(&mut self, expression: Arg) -> Result<()> {
        self.args.push(quote! {(#expression)});
        Ok(())
    }
}

#[proc_macro]
pub fn _pw_log_backend(tokens: TokenStream) -> TokenStream {
    let input = parse_macro_input!(tokens as PwLogArgs<CoreFmtFormatStringParser>);

    let generator = LogfGenerator::new(&input.log_level);

    match generate_core_fmt(generator, input.format_and_args.into()) {
        Ok(token_stream) => token_stream.into(),
        Err(e) => e.to_compile_error().into(),
    }
}

#[proc_macro]
pub fn _pw_logf_backend(tokens: TokenStream) -> TokenStream {
    let input = parse_macro_input!(tokens as PwLogArgs<PrintfFormatStringParser>);

    let generator = LogfGenerator::new(&input.log_level);

    match generate_core_fmt(generator, input.format_and_args.into()) {
        Ok(token_stream) => token_stream.into(),
        Err(e) => e.to_compile_error().into(),
    }
}
