// 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 anyhow::*;
use archivist_lib::logs::message::Severity;
use diagnostics_data::LogsData;
use fuchsia_async as fasync;
use fuchsia_inspect::{self as inspect, NumericProperty, Property};
use fuchsia_inspect_derive::Inspect;
use fuchsia_zircon as zx;
use futures::lock::Mutex;
use regex::Regex;
use std::collections::{hash_map::Entry, HashMap, VecDeque};
use std::convert::TryFrom;
use std::sync::Arc;

// Maximum number of GranularLogStatsRecords kept in a GranularLogStatsBucket.
const MAX_RECORDS_PER_BUCKET: usize = 100;

// Length of the interval corresdponding to a GranularLogStatsBucket.
const BUCKET_INTERVAL_IN_MINUTES: u64 = 15;

// Interval between per-component stats garbage collection runs to clean up stale stats.
const COMPONENT_STATS_GC_INTERVAL_HOURS: i64 = 1;

// `limit` in `stats_are_stale = freshness < fasync::Time::now() - zx::Duration::from_hours(limit)`.
const COMPONENT_STATS_FRESHNESS_EXPIRY_HOURS: i64 = 1;

/// Structure that holds stats for the log manager.
#[derive(Default, Inspect)]
pub struct LogManagerStats {
    total_logs: inspect::UintProperty,
    kernel_logs: inspect::UintProperty,
    logsink_logs: inspect::UintProperty,
    trace_logs: inspect::UintProperty,
    debug_logs: inspect::UintProperty,
    info_logs: inspect::UintProperty,
    warning_logs: inspect::UintProperty,
    error_logs: inspect::UintProperty,
    by_component: LogStatsByComponent,
    granular_stats: GranularLogStats,
    fatal_logs: inspect::UintProperty,
    closed_streams: inspect::UintProperty,
    unattributed_log_sinks: inspect::UintProperty,
}

#[derive(Inspect)]
struct LogStatsByComponent {
    // Note: This field is manually managed as the Inspect derive macro does
    // not yet support collections.
    #[inspect(skip)]
    components: Arc<Mutex<HashMap<String, Arc<ComponentLogStats>>>>,
    inspect_node: inspect::Node,

    // Maintain reference to periodic task that GCs stale `LogStatsByComponentGC`. This ensures that
    // the task will be aborted when this `LogStatsByComponent` is dropped.
    #[inspect(skip)]
    _gc_task: fasync::Task<()>,
}

impl LogStatsByComponent {
    fn new(gc_timeout: zx::Duration, inspect_node: inspect::Node) -> Self {
        let components = Arc::new(Mutex::new(HashMap::new()));
        let gc_components = components.clone();
        Self {
            components,
            inspect_node,
            _gc_task: fasync::Task::spawn(async move {
                loop {
                    {
                        let mut components = gc_components.lock().await;
                        let limit = (fasync::Time::now()
                            - zx::Duration::from_hours(COMPONENT_STATS_FRESHNESS_EXPIRY_HOURS))
                        .into_nanos();
                        components.retain(|_, stats| {
                            // TODO(fxbug.dev/56527): Report failure to access freshness somewhere.
                            //For now, assume failure to indicate a bad state and garbage collect
                            // such components (i.e., `false` below).
                            stats
                                .last_log_monotonic_nanos
                                .get()
                                .map_or(false, |freshness| freshness >= limit)
                        });
                    };
                    // Release `log_stats_component_gc` lock while waiting on timer.

                    fasync::Timer::new(fasync::Time::after(gc_timeout)).await;
                }
            }),
        }
    }

    pub async fn get_component_log_stats(&self, url: &str) -> Arc<ComponentLogStats> {
        let mut components = self.components.lock().await;
        match components.get(url) {
            Some(stats) => stats.clone(),
            None => {
                let mut stats = ComponentLogStats::default();
                // TODO(fxbug.dev/60396): Report failure to attach somewhere.
                let _ = stats.iattach(&self.inspect_node, url);
                let stats = Arc::new(stats);
                components.insert(url.to_string(), stats.clone());
                stats
            }
        }
    }
}

impl Default for LogStatsByComponent {
    fn default() -> Self {
        Self::new(
            zx::Duration::from_hours(COMPONENT_STATS_GC_INTERVAL_HOURS),
            inspect::Node::default(),
        )
    }
}

/// Holds up to 3 buckets, each bucket containing statistics for error & fatal log messages that
/// occured during an interval of length BUCKET_INTERVAL_IN_MINUTES. Logs with the same file and
/// line number are considered to be the same (even if their messages are not identical) and their
/// count will be exposed in inspect. Logs without file and line number are ignored.
#[derive(Default, Inspect)]
struct GranularLogStats {
    #[inspect(skip)]
    buckets: VecDeque<GranularLogStatsBucket>,
    inspect_node: inspect::Node,
}

impl GranularLogStats {
    pub fn record_log(&mut self, msg: &LogsData) {
        self.ensure_bucket().record_log(msg);
    }

    fn ensure_bucket(&mut self) -> &mut GranularLogStatsBucket {
        let bucket_id = fasync::Time::now().into_nanos() as u64
            / 1_000_000_000
            / 60
            / BUCKET_INTERVAL_IN_MINUTES;
        if self.buckets.is_empty() || self.buckets.back().unwrap().bucket_id < bucket_id {
            let mut new_bucket = GranularLogStatsBucket::default();
            let _ = new_bucket.iattach(&self.inspect_node, bucket_id.to_string());
            new_bucket.bucket_id = bucket_id;
            self.buckets.push_back(new_bucket);
            if self.buckets.len() > 3 {
                self.buckets.pop_front();
            }
        }
        self.buckets.back_mut().unwrap()
    }
}

#[derive(Hash, PartialEq, Eq, Clone)]
struct LogIdentifier {
    file_path: String,
    line_no: u64,
}

impl TryFrom<&LogsData> for LogIdentifier {
    type Error = anyhow::Error;

    fn try_from(msg: &LogsData) -> Result<Self, Self::Error> {
        // If the file path and line number fields exist in the hierarchy, the message was
        // written using the structured backend. Otherwise, it was written using the legacy
        // backend, and the file path and line number need to be parsed out of the message.
        if let (Some(file), Some(line)) = (msg.file_path(), msg.line_number()) {
            return Ok(LogIdentifier { file_path: file.to_string(), line_no: *line });
        }
        let re = Regex::new(r"^\[([^\(\]:]+)\((\d+)\)\]").unwrap();
        let msg_str = msg.msg().ok_or_else(|| format_err!("No message"))?;
        let cap =
            re.captures(msg_str).ok_or_else(|| format_err!("Message didn't match pattern"))?;
        let file = cap.get(1).ok_or_else(|| format_err!("Couldn't capture file path"))?.as_str();
        let line_str =
            cap.get(2).ok_or_else(|| format_err!("Couldn't capture line number"))?.as_str();
        let line = line_str.parse::<u64>()?;
        Ok(LogIdentifier { file_path: file.to_string(), line_no: line })
    }
}

#[derive(Default, Inspect)]
struct GranularLogStatsRecord {
    file_path: inspect::StringProperty,
    line_no: inspect::UintProperty,
    count: inspect::UintProperty,
    inspect_node: inspect::Node,
}

#[derive(Default, Inspect)]
struct GranularLogStatsBucket {
    #[inspect(skip)]
    stats: HashMap<LogIdentifier, GranularLogStatsRecord>,
    #[inspect(skip)]
    bucket_id: u64,
    overflowed: inspect::BoolProperty,
    inspect_node: inspect::Node,
}

impl GranularLogStatsBucket {
    pub fn record_log(&mut self, msg: &LogsData) {
        if msg.metadata.severity != Severity::Error && msg.metadata.severity != Severity::Fatal {
            return;
        }
        let id = match LogIdentifier::try_from(msg) {
            Ok(val) => val,
            Err(_) => return,
        };
        let num_records = self.stats.len();
        let record = match self.stats.entry(id.clone()) {
            Entry::Occupied(o) => o.into_mut(),
            Entry::Vacant(v) => {
                if num_records == MAX_RECORDS_PER_BUCKET {
                    self.overflowed.set(true);
                    return;
                }
                let next_id = num_records.to_string();
                let mut record = GranularLogStatsRecord::default();
                let _ = record.iattach(&self.inspect_node, next_id);
                record.file_path.set(&id.file_path);
                record.line_no.set(id.line_no);
                v.insert(record)
            }
        };
        record.count.add(1);
    }
}

#[derive(Inspect, Default)]
pub struct ComponentLogStats {
    last_log_monotonic_nanos: inspect::IntProperty,
    total_logs: inspect::UintProperty,
    trace_logs: inspect::UintProperty,
    debug_logs: inspect::UintProperty,
    info_logs: inspect::UintProperty,
    warning_logs: inspect::UintProperty,
    error_logs: inspect::UintProperty,
    fatal_logs: inspect::UintProperty,

    inspect_node: inspect::Node,
}

impl ComponentLogStats {
    pub fn record_log(&self, msg: &LogsData) {
        self.last_log_monotonic_nanos.set(fasync::Time::now().into_nanos());
        self.total_logs.add(1);
        match msg.metadata.severity {
            Severity::Trace => self.trace_logs.add(1),
            Severity::Debug => self.debug_logs.add(1),
            Severity::Info => self.info_logs.add(1),
            Severity::Warn => self.warning_logs.add(1),
            Severity::Error => self.error_logs.add(1),
            Severity::Fatal => self.fatal_logs.add(1),
        }
    }
}

impl LogManagerStats {
    /// Create a stat holder. Note that this needs to be attached to inspect in order
    /// for it to be inspected. See `fuchsia_inspect_derive::Inspect`.
    pub fn new_detached() -> Self {
        Self::default()
    }

    /// Record an incoming log from a given source.
    ///
    /// This method updates the counters based on the contents of the log message.
    pub fn record_log(&mut self, msg: &LogsData, source: LogSource) {
        self.total_logs.add(1);
        self.granular_stats.record_log(msg);
        match source {
            LogSource::Kernel => {
                self.kernel_logs.add(1);
            }
            LogSource::LogSink => {
                self.logsink_logs.add(1);
            }
        }
        match msg.metadata.severity {
            Severity::Trace => self.trace_logs.add(1),
            Severity::Debug => self.debug_logs.add(1),
            Severity::Info => self.info_logs.add(1),
            Severity::Warn => self.warning_logs.add(1),
            Severity::Error => self.error_logs.add(1),
            Severity::Fatal => self.fatal_logs.add(1),
        }
    }

    /// Returns the stats for a particular component specified by `identity`.
    pub async fn get_component_log_stats(&self, url: &str) -> Arc<ComponentLogStats> {
        self.by_component.get_component_log_stats(url).await
    }

    /// Record that we rejected a message.
    pub fn record_closed_stream(&self) {
        self.closed_streams.add(1);
    }

    /// Record an unattributed log message.
    pub fn record_unattributed(&self) {
        self.unattributed_log_sinks.add(1);
    }
}

/// Denotes the source of a particular log message.
pub enum LogSource {
    /// Log came from the kernel log (klog)
    Kernel,
    /// Log came from log sink
    LogSink,
}

#[cfg(test)]
mod tests {
    use {
        super::*, archivist_lib::logs::message::*, fuchsia_async as fasync,
        fuchsia_inspect::testing::*, fuchsia_inspect::*, fuchsia_zircon as zx, futures::Future,
        proptest::prelude::*, std::panic,
    };

    struct GranularTestState {
        exec: fasync::Executor,
        granular_stats: GranularLogStats,
        inspector: Inspector,
    }

    impl GranularTestState {
        fn new() -> Result<GranularTestState, anyhow::Error> {
            let exec = fasync::Executor::new_with_fake_time().expect("executor should build");
            exec.set_fake_time(fasync::Time::from_nanos(0));
            let inspector = Inspector::new();
            let mut granular_stats = GranularLogStats::default();
            granular_stats.iattach(inspector.root(), "granular_stats")?;
            Ok(GranularTestState {
                exec: exec,
                granular_stats: granular_stats,
                inspector: inspector,
            })
        }
    }

    #[test]
    fn granular_stats() -> Result<(), anyhow::Error> {
        let mut state = GranularTestState::new()?;

        let msg1 = create_message("[path/to/file.cpp(123)] Hello");
        let msg2 = create_message("[another_file.h(1)]");

        // Send |msg1|. Creates a new entry in bucket 0.
        state.granular_stats.record_log(&msg1);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Advance time but not enough to create a new bucket.
        state.exec.set_fake_time(fasync::Time::after(zx::Duration::from_minutes(5)));

        // Send |msg2|. Creates a new entry in bucket 0.
        state.granular_stats.record_log(&msg2);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 1u64
                },
                "1": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Advance time but not enough to create a new bucket.
        state.exec.set_fake_time(fasync::Time::after(zx::Duration::from_minutes(5)));

        // Send |msg1| again. No new entry is added. The existing entry will have its count
        // incremented.
        state.granular_stats.record_log(&msg1);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 2u64
                },
                "1": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Advance time enough to make create a new bucket.
        state.exec.set_fake_time(fasync::Time::after(zx::Duration::from_minutes(5)));

        // Send |msg2| again. A new entry must be added because a new bucket is created.
        state.granular_stats.record_log(&msg2);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 2u64
                },
                "1": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              },
              "1": {
                overflowed: false,
                "0": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Advance time enough to make create a new bucket.
        state.exec.set_fake_time(fasync::Time::after(zx::Duration::from_minutes(15)));

        // Send |msg1|. Creates a new entry in the new bucket.
        state.granular_stats.record_log(&msg1);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 2u64
                },
                "1": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              },
              "1": {
                overflowed: false,
                "0": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              },
              "2": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 1u64
                },
              }
            }
          }
        );

        // Advance time enough to make create a new bucket.
        state.exec.set_fake_time(fasync::Time::after(zx::Duration::from_minutes(15)));

        // Send |msg1|. Creates a new entry in the new bucket. The first bucket is dropped.
        state.granular_stats.record_log(&msg1);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "1": {
                overflowed: false,
                "0": {
                    "file_path": "another_file.h",
                    "line_no": 1u64,
                    "count": 1u64
                }
              },
              "2": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 1u64
                },
              },
              "3": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 123u64,
                    "count": 1u64
                },
              }
            }
          }
        );

        Ok(())
    }

    #[test]
    fn different_severities() -> Result<(), anyhow::Error> {
        let mut state = GranularTestState::new()?;

        let fatal_msg =
            create_message_with_severity("[path/to/file.cpp(121)] Hello", Severity::Fatal);
        let error_msg =
            create_message_with_severity("[path/to/file.cpp(122)] Hello", Severity::Error);
        let warn_msg =
            create_message_with_severity("[path/to/file.cpp(123)] Hello", Severity::Warn);
        let info_msg =
            create_message_with_severity("[path/to/file.cpp(124)] Hello", Severity::Info);
        let debug_msg =
            create_message_with_severity("[path/to/file.cpp(125)] Hello", Severity::Debug);
        let trace_msg =
            create_message_with_severity("[path/to/file.cpp(126)] Hello", Severity::Trace);

        // Fatal message should be recorded.
        state.granular_stats.record_log(&fatal_msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 121u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Error message should be recorded.
        state.granular_stats.record_log(&error_msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 121u64,
                    "count": 1u64
                },
                "1": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 122u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Lower severities should be ignored.
        state.granular_stats.record_log(&warn_msg);
        state.granular_stats.record_log(&info_msg);
        state.granular_stats.record_log(&debug_msg);
        state.granular_stats.record_log(&trace_msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 121u64,
                    "count": 1u64
                },
                "1": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 122u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        Ok(())
    }

    #[test]
    fn negative_edge_cases() -> Result<(), anyhow::Error> {
        // File and line not at the beginning
        verify_message_ignored("ERROR: [abc/xyz.cc(10)] dsafq")?;

        // No file or line number
        verify_message_ignored("[()] dsafq")?;
        verify_message_ignored("[(] dsafq")?;
        verify_message_ignored("[] dsafq")?;
        verify_message_ignored("() dsafq")?;
        verify_message_ignored("[ dsafq")?;
        verify_message_ignored("dsafq")?;

        // No line number
        verify_message_ignored("[daddsfsdafsadf()] dsafq")?;
        verify_message_ignored("[daddsfsdafsadf(] dsafq")?;
        verify_message_ignored("[daddsfsdafsadf] dsafq")?;

        // No file
        verify_message_ignored("[(12)] dsafq")?;
        verify_message_ignored("[12] dsafq")?;

        // Negative line number
        verify_message_ignored("[daddsfsdafsadf(-1)] dsafq")?;

        // Line number not a number
        verify_message_ignored("[daddsfsdafsadf(1a3)] dsafq")?;
        verify_message_ignored("[daddsfsdafsadf(xyz)] dsafq")?;
        verify_message_ignored("[daddsfsdafsadf(12.3)] dsafq")?;

        // Line number too large
        verify_message_ignored(
            "[daddsfsdafsadf(999999999999999999999999999999999999999999)] dsafq",
        )?;

        // Random unicode characters
        verify_message_ignored("𜌼:ع鱆髦頄񋉡j�삩ĕ낪�ˏ6ؔ𛙄񓈫b۷wuuN󡸲�劰ﵫ⮡ٸ󀁁")?;
        verify_message_ignored("[𜌼:ع鱆髦頄񋉡j�삩ĕ낪�ˏ6ؔ𛙄񓈫b۷wuuN(12)] Hi")?;

        Ok(())
    }

    #[test]
    fn positive_edge_cases() -> Result<(), anyhow::Error> {
        // Message is unicode.
        verify_file_and_line("[dir/file.cc(34)] 𜌼:ع鱆髦頄", "dir/file.cc", 34)?;

        // Message is empty.
        verify_file_and_line("[dir/file.cc(34)]", "dir/file.cc", 34)?;

        Ok(())
    }

    #[test]
    fn too_many_logs() -> Result<(), anyhow::Error> {
        let mut state = GranularTestState::new()?;

        for i in 1..MAX_RECORDS_PER_BUCKET + 2 {
            let msg_str = format!("[path/to/file.cpp({})] Hello", i);
            let msg = create_message(&msg_str);
            state.granular_stats.record_log(&msg);
            if i == MAX_RECORDS_PER_BUCKET + 1 {
                assert_inspect_tree!(state.inspector,
                   root: {
                       granular_stats: {
                           "0": contains {
                               overflowed: true
                           }
                       }
                });
            } else {
                assert_inspect_tree!(state.inspector,
                   root: {
                       granular_stats: {
                           "0": contains {
                               overflowed: false
                           }
                       }
                });
            }
        }

        // First MAX_RECORDS_PER_BUCKET logs should be recorded.
        let last_key = &(MAX_RECORDS_PER_BUCKET - 1).to_string();
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": contains {
                  var last_key: {
                    "file_path": "path/to/file.cpp",
                    "line_no": MAX_RECORDS_PER_BUCKET as u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // The last log should be ignored.
        let ignored_key = &MAX_RECORDS_PER_BUCKET.to_string();
        let tree_assertion = tree_assertion!(
              root: {
                granular_stats: {
                  "0": contains{
                      var ignored_key: contains {}
                  }
                }
              }
        );
        if tree_assertion.run(state.inspector.get_diagnostics_hierarchy().as_ref()).is_ok() {
            return Err(format_err!("Should not retain more than {} logs", MAX_RECORDS_PER_BUCKET));
        }

        // Repeat the first message another time. Its count should increase to 2.
        let msg = create_message("[path/to/file.cpp(1)] Hello");
        state.granular_stats.record_log(&msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": contains {
                "0": {
                    "file_path": "path/to/file.cpp",
                    "line_no": 1u64,
                    "count": 2u64
                }
              }
            }
          }
        );
        Ok(())
    }

    #[test]
    fn structured_log() -> Result<(), anyhow::Error> {
        let mut state = GranularTestState::new()?;

        // Simple structured log
        let msg = Message::new(
            zx::Time::from_nanos(1),
            Severity::Error,
            0, // size
            0, // dropped
            &*TEST_IDENTITY,
            LogsHierarchy::new(
                "root",
                vec![
                    LogsProperty::String(LogsField::Msg, "[irrelevant_tag(32)] Hello".to_string()),
                    LogsProperty::String(LogsField::FilePath, "path/to/file.cc".to_string()),
                    LogsProperty::Uint(LogsField::LineNumber, 123),
                ],
                vec![],
            ),
        );

        state.granular_stats.record_log(&msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cc",
                    "line_no": 123u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // Line number field missing. Should parse the message instead.
        let msg = Message::new(
            zx::Time::from_nanos(1),
            Severity::Error,
            0, // size
            0, // dropped
            &*TEST_IDENTITY,
            LogsHierarchy::new(
                "root",
                vec![
                    LogsProperty::String(LogsField::Msg, "[tag(1)] Msg".to_string()),
                    LogsProperty::String(LogsField::FilePath, "some/other/file.cc".to_string()),
                ],
                vec![],
            ),
        );
        state.granular_stats.record_log(&msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cc",
                    "line_no": 123u64,
                    "count": 1u64
                },
                "1": {
                    "file_path": "tag",
                    "line_no": 1u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        // No file field. Will parse the message instead.
        let msg = Message::new(
            zx::Time::from_nanos(1),
            Severity::Error,
            0, // size
            0, // dropped
            &*TEST_IDENTITY,
            LogsHierarchy::new(
                "root",
                vec![
                    LogsProperty::String(LogsField::Msg, "[file.rs(99)] Testing 1 2 3".to_string()),
                    LogsProperty::Uint(LogsField::LineNumber, 931),
                ],
                vec![],
            ),
        );
        state.granular_stats.record_log(&msg);
        assert_inspect_tree!(state.inspector,
          root: {
            granular_stats: {
              "0": {
                overflowed: false,
                "0": {
                    "file_path": "path/to/file.cc",
                    "line_no": 123u64,
                    "count": 1u64
                },
                "1": {
                    "file_path": "tag",
                    "line_no": 1u64,
                    "count": 1u64
                },
                "2": {
                    "file_path": "file.rs",
                    "line_no": 99u64,
                    "count": 1u64
                }
              }
            }
          }
        );

        Ok(())
    }

    struct ComponentTestState {
        executor: fasync::Executor,
        max_run_until_stalled_iterations: u32,
    }

    impl ComponentTestState {
        fn new(max_run_until_stalled_iterations: u32) -> Result<ComponentTestState, anyhow::Error> {
            let executor = fasync::Executor::new_with_fake_time().expect("executor should build");
            executor.set_fake_time(fasync::Time::from_nanos(0));
            Ok(ComponentTestState { executor, max_run_until_stalled_iterations })
        }

        fn set_time(&mut self, time: i64) {
            self.executor.set_fake_time(fasync::Time::from_nanos(time));
        }

        fn run<F>(&mut self, fut: &mut F)
        where
            F: Future + Unpin,
        {
            assert!(self.executor.run_until_stalled(fut).is_ready());
        }

        fn run_timers(&mut self) {
            assert!(self.executor.wake_expired_timers());
            self.sync();
        }

        fn sync(&mut self) {
            let mut i = 0;
            while self.executor.is_waiting() == fasync::WaitState::Ready {
                assert!(self.executor.run_until_stalled(&mut Box::pin(async {})).is_ready());
                i += 1;
                assert!(i < self.max_run_until_stalled_iterations);
            }
        }

        fn set_time_and_run_timers(&mut self, time: i64) {
            self.set_time(time);
            self.run_timers();
        }

        fn assert_no_timers(&mut self) {
            assert_eq!(None, self.executor.wake_next_timer());
        }

        fn assert_next_timer_at(&mut self, time: i64) {
            assert_eq!(
                fasync::WaitState::Waiting(fasync::Time::from_nanos(time)),
                self.executor.is_waiting()
            );
        }
    }

    #[test]
    fn component_stats_retained_then_dropped() -> Result<(), anyhow::Error> {
        // Setup clean state with predictable executor.
        let mut state = ComponentTestState::new(1000)?;
        state.assert_no_timers();

        let inspector = Inspector::new();
        let mut component_stats = LogStatsByComponent::default();
        component_stats.iattach(inspector.root(), "component_stats")?;
        let component_a = "a";
        let gc_interval_nanos =
            zx::Duration::from_hours(COMPONENT_STATS_GC_INTERVAL_HOURS).into_nanos();

        // Allow GC task to spin unp, then assert first GC timer set.
        state.sync();
        state.assert_next_timer_at(gc_interval_nanos);

        println!("About to run 1st access");

        // 1st access: stats lazily created.
        state.run(&mut Box::pin(async {
            println!("Started 1st access");
            let component_stats = component_stats.get_component_log_stats(&component_a).await;
            println!("Component stats unlocked");
            let msg = create_message_with_severity("[path/to/file.cpp(123)] Hello", Severity::Info);
            component_stats.record_log(&msg);
            println!("Log recorded");
            // Do not retain Arc; it should be kept alive by the timeout mechanism.
            drop(component_stats);
            println!("Component stats Arc dropped");
        }));
        assert_inspect_tree!(inspector,
            root: {
                component_stats: {
                    a: {
                        "last_log_monotonic_nanos": 0i64,
                        "total_logs": 1u64,
                        "trace_logs": 0u64,
                        "debug_logs": 0u64,
                        "info_logs": 1u64,
                        "warning_logs": 0u64,
                        "error_logs": 0u64,
                        "fatal_logs": 0u64,
                    }
                }
            }
        );

        // Advance to t=timeout: timer should fire, marking stats for GC, but not deleting them.
        state.set_time_and_run_timers(gc_interval_nanos);
        state.assert_next_timer_at(2 * gc_interval_nanos);

        // 2nd access: stats un-marked for GC.
        state.run(&mut Box::pin(async {
            let component_stats = component_stats.get_component_log_stats(&component_a).await;
            let msg = create_message_with_severity("[path/to/file.cpp(123)] Hello", Severity::Info);
            component_stats.record_log(&msg);
            // Do not retain Arc; it should be kept alive by the timeout mechanism.
            drop(component_stats);
        }));

        // Advance to t=2*timeout: timer should fire, marking stats (again) for GC.
        state.set_time_and_run_timers(2 * gc_interval_nanos);
        state.assert_next_timer_at(3 * gc_interval_nanos);

        // Access from another component, "b". Should not be GC'd in the next cycle (but rather,
        // the following) cycle.
        let component_b = "b";
        state.run(&mut Box::pin(async {
            let component_stats = component_stats.get_component_log_stats(&component_b).await;
            let msg =
                create_message_with_severity("[some/other/file.rs(456)] Goodbye", Severity::Info);
            component_stats.record_log(&msg);
            // Do not retain Arc; it should be kept alive by the timeout mechanism.
            drop(component_stats);
        }));

        // Both logs are in stats; freshness matches time of last recorded log.
        assert_inspect_tree!(inspector,
            root: {
                component_stats: {
                    a: {
                        "last_log_monotonic_nanos": gc_interval_nanos,
                        "total_logs": 2u64,
                        "trace_logs": 0u64,
                        "debug_logs": 0u64,
                        "info_logs": 2u64,
                        "warning_logs": 0u64,
                        "error_logs": 0u64,
                        "fatal_logs": 0u64,
                    },
                    b: {
                        "last_log_monotonic_nanos": 2 * gc_interval_nanos,
                        "total_logs": 1u64,
                        "trace_logs": 0u64,
                        "debug_logs": 0u64,
                        "info_logs": 1u64,
                        "warning_logs": 0u64,
                        "error_logs": 0u64,
                        "fatal_logs": 0u64,
                    }
                }
            }
        );

        // Advance to t=3*timeout: timer should fire, deleting "a" stats as garbage.
        state.set_time_and_run_timers(3 * gc_interval_nanos);
        state.assert_next_timer_at(4 * gc_interval_nanos);
        assert_inspect_tree!(inspector, root: {
            "component_stats": {
                b: {
                    "last_log_monotonic_nanos": 2 * gc_interval_nanos,
                    "total_logs": 1u64,
                    "trace_logs": 0u64,
                    "debug_logs": 0u64,
                    "info_logs": 1u64,
                    "warning_logs": 0u64,
                    "error_logs": 0u64,
                    "fatal_logs": 0u64,
                }
            }
        });

        // Advance to t=4*timeout: timer should fire, deleting "b" stats as garbage.
        state.set_time_and_run_timers(4 * gc_interval_nanos);
        state.assert_next_timer_at(5 * gc_interval_nanos);
        assert_inspect_tree!(inspector, root: {
            "component_stats": {}
        });

        Ok(())
    }

    proptest! {
        #[test]
        fn random_string(string in r"\p{Any}*") {
            prop_assert!(verify_message_ignored(&string).is_ok());
        }

        #[test]
        fn random_file_and_line(file in r"[a-zA-Z0-9_/\.]+", line in 1..999999, msg in r"\p{Any}*") {
            let msg_str = format!("[{}({})] {}", file, line, msg);
            prop_assert!(verify_file_and_line(&msg_str, &file, line as u64).is_ok());
        }
    }

    fn create_message(msg: &str) -> Message {
        create_message_with_severity(msg, Severity::Error)
    }

    fn create_message_with_severity(msg: &str, severity: Severity) -> Message {
        Message::new(
            zx::Time::from_nanos(1),
            severity,
            METADATA_SIZE + 1 + msg.len(),
            0, // dropped
            &*TEST_IDENTITY,
            LogsHierarchy::new(
                "root",
                vec![LogsProperty::String(LogsField::Msg, msg.to_string())],
                vec![],
            ),
        )
    }

    fn verify_message_ignored(msg_str: &str) -> Result<(), anyhow::Error> {
        let mut state = GranularTestState::new()?;
        let msg = create_message(msg_str);
        state.granular_stats.record_log(&msg);
        let tree_assertion = tree_assertion!(
              root: {
                granular_stats: {
                    "0": {
                        overflowed: false,
                    }
                }
              }
        );
        match tree_assertion.run(state.inspector.get_diagnostics_hierarchy().as_ref()) {
            Ok(()) => Ok(()),
            Err(e) => Err(format_err!("Message not ignored: {} \n {}", msg_str, e)),
        }
    }

    fn verify_file_and_line(msg_str: &str, file: &str, line: u64) -> Result<(), anyhow::Error> {
        let mut state = GranularTestState::new()?;
        let msg = create_message(msg_str);
        state.granular_stats.record_log(&msg);
        let tree_assertion = tree_assertion!(
              root: {
                granular_stats: {
                  "0": {
                    overflowed: false,
                    "0": {
                        "file_path": file.to_string(),
                        "line_no": line,
                        "count": 1u64,
                    }
                  }
                }
              }
        );
        match tree_assertion.run(state.inspector.get_diagnostics_hierarchy().as_ref()) {
            Ok(()) => Ok(()),
            Err(e) => Err(format_err!("Parsing failed for message: {} \n {}", msg_str, e)),
        }
    }
}
