// Copyright 2020 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 archivist_lib::logs::debuglog::KERNEL_URL;
use argh::FromArgs;
use diagnostics_reader::{ArchiveReader, Logs};
use fidl_fuchsia_diagnostics::{ArchiveAccessorMarker, ArchiveAccessorProxy};
use fuchsia_async as fasync;
use fuchsia_component::{client::connect_to_service, server::ServiceFs};
use fuchsia_inspect::{
    component::{health, inspector},
    health::Reporter,
};
use fuchsia_inspect_derive::WithInspect;
use futures::{future::join, prelude::*};
use tracing::*;

/// The name of the subcommand and the logs-tag.
pub const PROGRAM_NAME: &str = "log-stats";

mod stats;
use stats::{LogManagerStats, LogSource};

/// Empty command line args, just to give Launcher the subcommand name "log-stats"
#[derive(FromArgs, Debug, PartialEq)]
#[argh(subcommand, name = "log-stats")]
pub struct CommandLine {}

pub async fn main() -> Result<(), anyhow::Error> {
    let mut service_fs = ServiceFs::new_local();
    service_fs.take_and_serve_directory_handle()?;

    inspector().serve(&mut service_fs)?;
    health().set_starting_up();
    let stats = LogManagerStats::default().with_inspect(inspector().root(), "log_stats")?;

    let accessor = connect_to_service::<ArchiveAccessorMarker>()?;

    health().set_ok();
    info!("Maintaining.");
    join(maintain(stats, accessor), service_fs.collect::<()>()).await;
    info!("Exiting.");
    Ok(())
}

async fn maintain(mut stats: LogManagerStats, archive: ArchiveAccessorProxy) {
    let reader = ArchiveReader::new().with_archive(archive);

    let (mut logs, mut errors) = reader.snapshot_then_subscribe::<Logs>().unwrap().split_streams();
    let _errors = fasync::Task::spawn(async move {
        while let Some(error) = errors.next().await {
            panic!("Error encountered while retrieving logs: {}", error);
        }
    });

    while let Some(log) = logs.next().await {
        let source = if log.metadata.component_url == KERNEL_URL {
            LogSource::Kernel
        } else {
            LogSource::LogSink
        };
        stats.record_log(&log, source);
        stats.get_component_log_stats(&log.metadata.component_url).await.record_log(&log);
    }
}

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

    #[fasync::run_singlethreaded(test)]
    async fn smoke_test() {
        assert!(true);
    }
}
