// Copyright (C) 2023-2026 Free Software Foundation, Inc.
//
// This file is part of the GNU Proc Macro Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

use bridge::{ffistring::FFIString, group::Group, ident::Ident, literal::Literal, punct::Punct};
use std::convert::TryInto;
use std::fmt;
use std::slice;
use std::str::FromStr;
use LexError;

type ExternalTokenTree = crate::TokenTree;
type ExternalTokenStream = crate::TokenStream;

extern "C" {
    fn TokenStream__new() -> TokenStream;
    fn TokenStream__with_capacity(capacity: u64) -> TokenStream;
    fn TokenStream__push(stream: *mut TokenStream, tree: TokenTree);
    fn TokenStream__from_string(str: FFIString, ts: *mut TokenStream) -> bool;
    fn TokenStream__clone(ts: *const TokenStream) -> TokenStream;
    fn TokenStream__drop(stream: *mut TokenStream);
}

#[repr(C)]
#[derive(Clone)]
pub enum TokenTree {
    Group(Group),
    Ident(Ident),
    Punct(Punct),
    Literal(Literal),
}

impl fmt::Display for TokenTree {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TokenTree::Group(group) => group.fmt(f),
            TokenTree::Ident(ident) => ident.fmt(f),
            TokenTree::Punct(punct) => punct.fmt(f),
            TokenTree::Literal(literal) => literal.fmt(f),
        }
    }
}

impl From<ExternalTokenTree> for TokenTree {
    fn from(value: ExternalTokenTree) -> Self {
        match value {
            ExternalTokenTree::Group(g) => TokenTree::Group(g.0),
            ExternalTokenTree::Ident(i) => TokenTree::Ident(i.0),
            ExternalTokenTree::Punct(p) => TokenTree::Punct(p.0),
            ExternalTokenTree::Literal(l) => TokenTree::Literal(l.0),
        }
    }
}

#[repr(C)]
#[derive(Debug)]
pub struct TokenStream {
    pub(crate) data: *const TokenTree,
    pub(crate) size: u64,
    capacity: u64,
}

impl TokenStream {
    pub fn new() -> Self {
        unsafe { TokenStream__new() }
    }

    fn with_capacity(capacity: u64) -> Self {
        unsafe { TokenStream__with_capacity(capacity) }
    }

    fn push(&mut self, tree: TokenTree) {
        unsafe { TokenStream__push(self as *mut TokenStream, tree) }
    }

    pub fn is_empty(&self) -> bool {
        0 == self.size
    }

    pub fn from_iterator<I>(it: I) -> Self
    where
        I: IntoIterator<Item = ExternalTokenStream>,
    {
        let it = it.into_iter();
        let mut result = TokenStream::with_capacity(it.size_hint().0.try_into().unwrap());
        for stream in it {
            for item in stream.into_iter() {
                result.push(item.into());
            }
        }
        result
    }

    pub fn from_tree_iterator<I>(it: I) -> Self
    where
        I: IntoIterator<Item = ExternalTokenTree>,
    {
        let it = it.into_iter();
        let mut result = TokenStream::with_capacity(it.size_hint().0.try_into().unwrap());
        for item in it {
            result.push(item.into());
        }
        result
    }
}

impl Extend<ExternalTokenTree> for TokenStream {
    fn extend<I: IntoIterator<Item = ExternalTokenTree>>(&mut self, trees: I) {
        for tt in trees {
            self.push(tt.into())
        }
    }
}

impl Extend<ExternalTokenStream> for TokenStream {
    fn extend<I: IntoIterator<Item = ExternalTokenStream>>(&mut self, streams: I) {
        for stream in streams {
            for tt in stream {
                self.push(tt.into());
            }
        }
    }
}

impl fmt::Display for TokenStream {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for i in unsafe { slice::from_raw_parts(self.data, self.size.try_into().unwrap()) } {
            i.fmt(f)?;
            match i {
                TokenTree::Punct(_) => (),
                _ => f.write_str(" ")?,
            }
        }
        Ok(())
    }
}

impl FromStr for TokenStream {
    type Err = LexError;
    fn from_str(string: &str) -> Result<Self, LexError> {
        let mut ts = TokenStream::new();
        if unsafe { TokenStream__from_string(string.into(), &mut ts as *mut TokenStream) } {
            Err(LexError)
        } else {
            Ok(ts)
        }
    }
}

impl Clone for TokenStream {
    fn clone(&self) -> Self {
        unsafe { TokenStream__clone(self as *const TokenStream) }
    }
}

impl Drop for TokenStream {
    fn drop(&mut self) {
        unsafe { TokenStream__drop(self as *mut TokenStream) }
    }
}
