/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *     http://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 std::time::Duration;
use tokio::io::{AsyncRead, AsyncReadExt};
use tokio_util::sync::CancellationToken;

const TAIL_BYTES: usize = 65_536;
pub(crate) const DRAIN: Duration = Duration::from_secs(2);

#[derive(Default)]
pub(crate) struct Tail {
    bytes: Vec<u8>,
    pub truncated: bool,
}

impl Tail {
    fn push(&mut self, bytes: &[u8]) {
        let overflow = (self.bytes.len() + bytes.len()).saturating_sub(TAIL_BYTES);
        if overflow > 0 {
            self.truncated = true;
            if overflow >= self.bytes.len() {
                self.bytes.clear();
                self.bytes
                    .extend_from_slice(&bytes[bytes.len().saturating_sub(TAIL_BYTES)..]);
                return;
            }
            self.bytes.drain(..overflow);
        }
        self.bytes.extend_from_slice(bytes);
    }

    pub fn text(&mut self) -> String {
        let mut start = 0;
        // A byte tail can begin inside a valid UTF-8 code point.
        if self.truncated {
            while start < self.bytes.len() && self.bytes[start] & 0xc0 == 0x80 {
                start += 1;
            }
        }
        let text = String::from_utf8_lossy(&self.bytes[start..]);
        // Invalid source bytes can expand to replacement characters.
        let mut start = text.len().saturating_sub(TAIL_BYTES);
        while !text.is_char_boundary(start) {
            start += 1;
        }
        self.truncated |= start > 0;
        text[start..].to_owned()
    }
}

pub(crate) async fn capture(
    mut pipe: impl AsyncRead + Unpin,
    exited: CancellationToken,
    observer: Option<(
        tokio::sync::mpsc::Sender<crate::PipeEvent>,
        maka_agent_facts::shell_run::PipeStream,
    )>,
) -> Tail {
    let mut tail = Tail::default();
    let deadline = async {
        exited.cancelled().await;
        tokio::time::sleep(DRAIN).await
    };
    tokio::pin!(deadline);
    let mut buffer = [0; 8192];
    loop {
        tokio::select! {
            biased;
            _ = &mut deadline => { tail.truncated = true; break; }
            read = pipe.read(&mut buffer) => match read {
                Ok(0) => break,
                Ok(n) => {
                    tail.push(&buffer[..n]);
                    if let Some((observer, stream)) = &observer {
                        // The bounded observer may apply backpressure, but root
                        // exit still bounds drain even if its consumer stops.
                        let event = crate::PipeEvent::Output { stream: *stream, bytes: buffer[..n].to_vec() };
                        tokio::select! {
                            biased;
                            _ = &mut deadline => { tail.truncated = true; break; }
                            _ = observer.send(event) => {}
                        }
                    }
                },
                Err(_) => { tail.truncated = true; break; }
            }
        }
    }
    tail
}

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

    #[test]
    fn replacement_expansion_is_bounded_and_marked_truncated() {
        let mut tail = Tail::default();
        tail.push(&vec![0xff; TAIL_BYTES]);
        let text = tail.text();
        assert!(text.len() <= TAIL_BYTES);
        assert!(tail.truncated);
        assert!(text.chars().all(|character| character == '\u{fffd}'));
    }
}
