// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::terminal::Terminal,
    anyhow::Error,
    fuchsia_async::{self as fasync, OnSignals},
    fuchsia_zircon::{self as zx, AsHandleRef},
    std::io::sink,
    term_model::{ansi::Processor, event::EventListener},
};

pub trait LogClient: 'static + Clone {
    type Listener;

    fn create_terminal(&self, id: u32, title: String) -> Result<Terminal<Self::Listener>, Error>;
    fn request_update(&self, id: u32);
}

pub struct Log;

impl Log {
    pub fn start<T: LogClient>(
        read_only_debuglog: zx::DebugLog,
        client: &T,
        id: u32,
    ) -> Result<(), Error>
    where
        <T as LogClient>::Listener: EventListener,
    {
        let client = client.clone();
        let terminal =
            client.create_terminal(id, "debuglog".to_string()).expect("failed to create terminal");
        let term = terminal.clone_term();

        // Get our process koid so we can filter out our own debug messages from the log.
        let proc_koid =
            fuchsia_runtime::process_self().get_koid().expect("failed to get koid for process");

        fasync::Task::local(async move {
            let mut sink = sink();
            let mut parser = Processor::new();

            loop {
                let on_signal = OnSignals::new(&read_only_debuglog, zx::Signals::LOG_READABLE);
                on_signal.await.expect("failed to wait for log readable");

                loop {
                    match read_only_debuglog.read() {
                        Ok(record) => {
                            // Don't print log messages from ourself.
                            if record.pid == proc_koid.raw_koid() {
                                continue;
                            }

                            let mut term = term.borrow_mut();

                            // Write prefix with time stamps and ids.
                            let prefix = format!(
                                "\u{001b}[32m{:05}.{:03}\u{001b}[39m] \u{001b}[31m{:05}.\u{001b}[36m{:05}\u{001b}[39m> ",
                                record.timestamp / 1_000_000_000,
                                (record.timestamp / 1_000_000) % 1_000,
                                record.pid,
                                record.tid,
                            );
                            for byte in prefix.as_bytes() {
                                parser.advance(&mut *term, *byte, &mut sink);
                            }

                            // Ignore any trailing newline character.
                            let mut datalen = record.datalen as usize;
                            if datalen > 0 && record.data[datalen - 1] == '\n' as u8 {
                                datalen -= 1;
                            }

                            // Write record data.
                            for byte in &record.data[0..datalen] {
                                parser.advance(&mut *term, *byte, &mut sink);
                            }

                            // Write carriage return and newline.
                            for byte in "\r\n".as_bytes() {
                                parser.advance(&mut *term, *byte, &mut sink);
                            }

                            // Request terminal update.
                            client.request_update(id);
                        }
                        Err(status) if status == zx::Status::SHOULD_WAIT => {
                            break;
                        }
                        Err(_) => {
                            let mut term = term.borrow_mut();
                            for byte in "\r\n<<LOG ERROR>>".as_bytes() {
                                parser.advance(&mut *term, *byte, &mut sink);
                            }

                            // Request terminal update.
                            client.request_update(id);
                            break;
                        }
                    }
                }
            }
        })
        .detach();

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use {super::*, crate::colors::ColorScheme, fuchsia_async as fasync, term_model::event::Event};

    #[derive(Default)]
    struct TestListener;

    impl EventListener for TestListener {
        fn send_event(&self, _event: Event) {}
    }

    #[derive(Default, Clone)]
    struct TestLogClient;

    impl LogClient for TestLogClient {
        type Listener = TestListener;

        fn create_terminal(
            &self,
            _id: u32,
            title: String,
        ) -> Result<Terminal<Self::Listener>, Error> {
            Ok(Terminal::new(TestListener::default(), title, ColorScheme::default(), 1024, None))
        }
        fn request_update(&self, _id: u32) {}
    }

    #[fasync::run_singlethreaded(test)]
    async fn can_start_log() -> Result<(), Error> {
        let resource = zx::Resource::from(zx::Handle::invalid());
        let debuglog = zx::DebugLog::create(&resource, zx::DebugLogOpts::empty()).unwrap();
        let client = TestLogClient::default();
        let _ = Log::start(debuglog, &client, 0)?;
        Ok(())
    }
}
