//! Buffered Base64 encoder.

use crate::{
    Encoding,
    Error::{self, InvalidLength},
    LineEnding, MIN_LINE_WIDTH,
};
use core::{cmp, marker::PhantomData, str};

#[cfg(feature = "std")]
use std::io;

#[cfg(doc)]
use crate::{Base64, Base64Unpadded};

/// Stateful Base64 encoder with support for buffered, incremental encoding.
///
/// The `E` type parameter can be any type which impls [`Encoding`] such as
/// [`Base64`] or [`Base64Unpadded`].
pub struct Encoder<'o, E: Encoding> {
    /// Output buffer.
    output: &'o mut [u8],

    /// Cursor within the output buffer.
    position: usize,

    /// Block buffer used for non-block-aligned data.
    block_buffer: BlockBuffer,

    /// Configuration and state for line-wrapping the output at a specified
    /// column.
    line_wrapper: Option<LineWrapper>,

    /// Phantom parameter for the Base64 encoding in use.
    encoding: PhantomData<E>,
}

impl<'o, E: Encoding> Encoder<'o, E> {
    /// Create a new encoder which writes output to the given byte slice.
    ///
    /// Output constructed using this method is not line-wrapped.
    pub fn new(output: &'o mut [u8]) -> Result<Self, Error> {
        if output.is_empty() {
            return Err(InvalidLength);
        }

        Ok(Self {
            output,
            position: 0,
            block_buffer: BlockBuffer::default(),
            line_wrapper: None,
            encoding: PhantomData,
        })
    }

    /// Create a new encoder which writes line-wrapped output to the given byte
    /// slice.
    ///
    /// Output will be wrapped at the specified interval, using the provided
    /// line ending. Use [`LineEnding::default()`] to use the conventional line
    /// ending for the target OS.
    ///
    /// Minimum allowed line width is 4.
    pub fn new_wrapped(
        output: &'o mut [u8],
        width: usize,
        ending: LineEnding,
    ) -> Result<Self, Error> {
        let mut encoder = Self::new(output)?;
        encoder.line_wrapper = Some(LineWrapper::new(width, ending)?);
        Ok(encoder)
    }

    /// Encode the provided buffer as Base64, writing it to the output buffer.
    ///
    /// # Returns
    /// - `Ok(bytes)` if the expected amount of data was read
    /// - `Err(Error::InvalidLength)` if there is insufficient space in the output buffer
    pub fn encode(&mut self, mut input: &[u8]) -> Result<(), Error> {
        // If there's data in the block buffer, fill it
        if !self.block_buffer.is_empty() {
            self.process_buffer(&mut input)?;
        }

        while !input.is_empty() {
            // Attempt to encode a stride of block-aligned data
            let in_blocks = input.len() / 3;
            let out_blocks = self.remaining().len() / 4;
            let mut blocks = cmp::min(in_blocks, out_blocks);

            // When line wrapping, cap the block-aligned stride at near/at line length
            if let Some(line_wrapper) = &self.line_wrapper {
                line_wrapper.wrap_blocks(&mut blocks)?;
            }

            if blocks > 0 {
                let len = blocks.checked_mul(3).ok_or(InvalidLength)?;
                let (in_aligned, in_rem) = input.split_at(len);
                input = in_rem;
                self.perform_encode(in_aligned)?;
            }

            // If there's remaining non-aligned data, fill the block buffer
            if !input.is_empty() {
                self.process_buffer(&mut input)?;
            }
        }

        Ok(())
    }

    /// Get the position inside of the output buffer where the write cursor
    /// is currently located.
    pub fn position(&self) -> usize {
        self.position
    }

    /// Finish encoding data, returning the resulting Base64 as a `str`.
    pub fn finish(self) -> Result<&'o str, Error> {
        self.finish_with_remaining().map(|(base64, _)| base64)
    }

    /// Finish encoding data, returning the resulting Base64 as a `str`
    /// along with the remaining space in the output buffer.
    pub fn finish_with_remaining(mut self) -> Result<(&'o str, &'o mut [u8]), Error> {
        if !self.block_buffer.is_empty() {
            let buffer_len = self.block_buffer.position;
            let block = self.block_buffer.bytes;
            self.perform_encode(&block[..buffer_len])?;
        }

        let (base64, remaining) = self.output.split_at_mut(self.position);
        Ok((str::from_utf8(base64)?, remaining))
    }

    /// Borrow the remaining data in the buffer.
    fn remaining(&mut self) -> &mut [u8] {
        &mut self.output[self.position..]
    }

    /// Fill the block buffer with data, consuming and encoding it when the
    /// buffer is full.
    fn process_buffer(&mut self, input: &mut &[u8]) -> Result<(), Error> {
        self.block_buffer.fill(input)?;

        if self.block_buffer.is_full() {
            let block = self.block_buffer.take();
            self.perform_encode(&block)?;
        }

        Ok(())
    }

    /// Perform Base64 encoding operation.
    fn perform_encode(&mut self, input: &[u8]) -> Result<usize, Error> {
        let mut len = E::encode(input, self.remaining())?.as_bytes().len();

        // Insert newline characters into the output as needed
        if let Some(line_wrapper) = &mut self.line_wrapper {
            line_wrapper.insert_newlines(&mut self.output[self.position..], &mut len)?;
        }

        self.position = self.position.checked_add(len).ok_or(InvalidLength)?;
        Ok(len)
    }
}

#[cfg(feature = "std")]
impl<'o, E: Encoding> io::Write for Encoder<'o, E> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.encode(buf)?;
        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        // TODO(tarcieri): return an error if there's still data remaining in the buffer?
        Ok(())
    }
}

/// Base64 encode buffer for a 1-block output.
///
/// This handles a partial block of data, i.e. data which hasn't been
#[derive(Clone, Default, Debug)]
struct BlockBuffer {
    /// 3 decoded bytes to be encoded to a 4-byte Base64-encoded input.
    bytes: [u8; Self::SIZE],

    /// Position within the buffer.
    position: usize,
}

impl BlockBuffer {
    /// Size of the buffer in bytes: 3-bytes of unencoded input which
    /// Base64 encode to 4-bytes of output.
    const SIZE: usize = 3;

    /// Fill the remaining space in the buffer with the input data.
    fn fill(&mut self, input: &mut &[u8]) -> Result<(), Error> {
        let remaining = Self::SIZE.checked_sub(self.position).ok_or(InvalidLength)?;
        let len = cmp::min(input.len(), remaining);
        self.bytes[self.position..][..len].copy_from_slice(&input[..len]);
        self.position = self.position.checked_add(len).ok_or(InvalidLength)?;
        *input = &input[len..];
        Ok(())
    }

    /// Take the output buffer, resetting the position to 0.
    fn take(&mut self) -> [u8; Self::SIZE] {
        debug_assert!(self.is_full());
        let result = self.bytes;
        *self = Default::default();
        result
    }

    /// Is the buffer empty?
    fn is_empty(&self) -> bool {
        self.position == 0
    }

    /// Is the buffer full?
    fn is_full(&self) -> bool {
        self.position == Self::SIZE
    }
}

/// Helper for wrapping Base64 at a given line width.
#[derive(Debug)]
struct LineWrapper {
    /// Number of bytes remaining in the current line.
    remaining: usize,

    /// Column at which Base64 should be wrapped.
    width: usize,

    /// Newline characters to use at the end of each line.
    ending: LineEnding,
}

impl LineWrapper {
    /// Create a new linewrapper.
    fn new(width: usize, ending: LineEnding) -> Result<Self, Error> {
        if width < MIN_LINE_WIDTH {
            return Err(InvalidLength);
        }

        Ok(Self {
            remaining: width,
            width,
            ending,
        })
    }

    /// Wrap the number of blocks to encode near/at EOL.
    fn wrap_blocks(&self, blocks: &mut usize) -> Result<(), Error> {
        if blocks.checked_mul(4).ok_or(InvalidLength)? >= self.remaining {
            *blocks = self.remaining / 4;
        }

        Ok(())
    }

    /// Insert newlines into the output buffer as needed.
    fn insert_newlines(&mut self, mut buffer: &mut [u8], len: &mut usize) -> Result<(), Error> {
        let mut buffer_len = *len;

        if buffer_len <= self.remaining {
            self.remaining = self
                .remaining
                .checked_sub(buffer_len)
                .ok_or(InvalidLength)?;

            return Ok(());
        }

        buffer = &mut buffer[self.remaining..];
        buffer_len = buffer_len
            .checked_sub(self.remaining)
            .ok_or(InvalidLength)?;

        // The `wrap_blocks` function should ensure the buffer is no larger than a Base64 block
        debug_assert!(buffer_len <= 4, "buffer too long: {}", buffer_len);

        // Ensure space in buffer to add newlines
        let buffer_end = buffer_len
            .checked_add(self.ending.len())
            .ok_or(InvalidLength)?;

        if buffer_end >= buffer.len() {
            return Err(InvalidLength);
        }

        // Shift the buffer contents to make space for the line ending
        for i in (0..buffer_len).rev() {
            buffer[i.checked_add(self.ending.len()).ok_or(InvalidLength)?] = buffer[i];
        }

        buffer[..self.ending.len()].copy_from_slice(self.ending.as_bytes());
        *len = (*len).checked_add(self.ending.len()).ok_or(InvalidLength)?;
        self.remaining = self.width.checked_sub(buffer_len).ok_or(InvalidLength)?;

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use crate::{alphabet::Alphabet, test_vectors::*, Base64, Base64Unpadded, Encoder, LineEnding};

    #[test]
    fn encode_padded() {
        encode_test::<Base64>(PADDED_BIN, PADDED_BASE64, None);
    }

    #[test]
    fn encode_unpadded() {
        encode_test::<Base64Unpadded>(UNPADDED_BIN, UNPADDED_BASE64, None);
    }

    #[test]
    fn encode_multiline_padded() {
        encode_test::<Base64>(MULTILINE_PADDED_BIN, MULTILINE_PADDED_BASE64, Some(70));
    }

    #[test]
    fn encode_multiline_unpadded() {
        encode_test::<Base64Unpadded>(MULTILINE_UNPADDED_BIN, MULTILINE_UNPADDED_BASE64, Some(70));
    }

    #[test]
    fn no_trailing_newline_when_aligned() {
        let mut buffer = [0u8; 64];
        let mut encoder = Encoder::<Base64>::new_wrapped(&mut buffer, 64, LineEnding::LF).unwrap();
        encoder.encode(&[0u8; 48]).unwrap();

        // Ensure no newline character is present in this case
        assert_eq!(
            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            encoder.finish().unwrap()
        );
    }

    /// Core functionality of an encoding test.
    fn encode_test<V: Alphabet>(input: &[u8], expected: &str, wrapped: Option<usize>) {
        let mut buffer = [0u8; 1024];

        for chunk_size in 1..input.len() {
            let mut encoder = match wrapped {
                Some(line_width) => {
                    Encoder::<V>::new_wrapped(&mut buffer, line_width, LineEnding::LF)
                }
                None => Encoder::<V>::new(&mut buffer),
            }
            .unwrap();

            for chunk in input.chunks(chunk_size) {
                encoder.encode(chunk).unwrap();
            }

            assert_eq!(expected, encoder.finish().unwrap());
        }
    }
}
