// 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::Error;
use archivist_lib::logs::redact::{REDACTED_CANARY_MESSAGE, UNREDACTED_CANARY_MESSAGE};
use diagnostics_data::LogsData;
use diagnostics_reader::{ArchiveReader, Logs};
use fidl_fuchsia_diagnostics::ArchiveAccessorMarker;
use fidl_fuchsia_sys::ComponentControllerEvent;
use fuchsia_async::Task;
use fuchsia_component::client::launcher;
use fuchsia_component::client::{App, AppBuilder};
use futures::prelude::*;
use std::{
    fs::{create_dir_all, remove_dir_all, write, File},
    path::Path,
};
use tracing::debug;

#[fuchsia::test]
async fn canary_is_redacted_with_filtering() {
    debug!("test started");
    let env = TestEnv::with_filtering().await.unwrap();
    let redacted = env.get_feedback_canary().await;
    assert_eq!(redacted.msg().unwrap().trim_end(), REDACTED_CANARY_MESSAGE);
}

#[fuchsia::test]
async fn canary_is_unredacted_without_filtering() {
    debug!("test started");
    let env = TestEnv::without_filtering().await.unwrap();
    let redacted = env.get_feedback_canary().await;
    assert_eq!(redacted.msg().unwrap().trim_end(), UNREDACTED_CANARY_MESSAGE);
}

const ARCHIVIST_URL: &str =
    "fuchsia-pkg://fuchsia.com/test-logs-redaction#meta/own-logs-consuming-archivist.cmx";
const ARCHIVIST_CONFIG: &[u8] = include_bytes!("../configs/archivist_config.json");

struct TestEnv {
    _archivist: App,
    _monitor_archivist: Task<()>,
    feedback_reader: ArchiveReader,
    all_reader: ArchiveReader,
}

impl TestEnv {
    /// Get the redaction canary message from the FeedbackArchiveAccessor reader. Relies on ordering
    /// being identical between ArchiveAccessor snapshot and FeedbackArchiveAccessor snapshot.
    async fn get_feedback_canary(&self) -> LogsData {
        debug!("retrieving logs from feedback accessor");
        let feedback_logs = self.feedback_reader.snapshot::<Logs>().await.unwrap();
        let all_logs = self.all_reader.snapshot::<Logs>().await.unwrap();

        let (unredacted, redacted) = all_logs
            .into_iter()
            .zip(feedback_logs)
            .find(|(u, _)| u.msg().unwrap().contains(UNREDACTED_CANARY_MESSAGE))
            .unwrap();
        debug!(unredacted = %unredacted.msg().unwrap());
        redacted
    }

    async fn without_filtering() -> Result<Self, Error> {
        Self::new(false).await
    }

    async fn with_filtering() -> Result<Self, Error> {
        Self::new(true).await
    }

    async fn new(filter: bool) -> Result<Self, Error> {
        debug!(%filter, "creating test environment");
        let config_path = Path::new("/tmp/config/data");
        let feedback_path = config_path.join("feedback");
        remove_dir_all(config_path).unwrap_or_default();
        create_dir_all(&feedback_path)?;

        write(config_path.join("archivist_config.json"), ARCHIVIST_CONFIG)?;

        // VERY IMPORTANT -- the feedback pipeline disables all filtering if no files present
        write(feedback_path.join("empty.cfg"), b"")?;

        if !filter {
            write(
                config_path.join("feedback/DISABLE_FILTERING.txt"),
                "This file disables filtering",
            )?;
        }

        let _archivist = AppBuilder::new(ARCHIVIST_URL)
            .add_dir_to_namespace("/config/data".into(), File::open(config_path)?)?
            .spawn(&launcher()?)?;

        // first we'll wait for the archivist to start, then make sure it doesn't stop in the background
        let mut component_stream = _archivist.controller().take_event_stream();
        let handle_termination = |code, reason| {
            panic!("Archivist terminated unexpectedly. Code: {}. Reason: {:?}", code, reason);
        };

        debug!("waiting for archivist to start");
        match component_stream.try_next().await?.unwrap() {
            ComponentControllerEvent::OnDirectoryReady {} => debug!("archivist directory ready"),
            ComponentControllerEvent::OnTerminated { return_code, termination_reason } => {
                handle_termination(return_code, termination_reason)
            }
        }

        let _monitor_archivist = Task::spawn(async move {
            while let Some(next) = component_stream.try_next().await.unwrap() {
                match next {
                    ComponentControllerEvent::OnDirectoryReady {} => {
                        panic!("received dir ready 2x")
                    }
                    ComponentControllerEvent::OnTerminated { return_code, termination_reason } => {
                        handle_termination(return_code, termination_reason)
                    }
                }
            }
        });

        let all_reader = ArchiveReader::new()
            .with_archive(_archivist.connect_to_service::<ArchiveAccessorMarker>().unwrap());
        let feedback_reader = ArchiveReader::new().with_archive(
            _archivist
                .connect_to_named_service::<ArchiveAccessorMarker>(
                    "fuchsia.diagnostics.FeedbackArchiveAccessor",
                )
                .unwrap(),
        );

        debug!("test env created");
        Ok(TestEnv { _archivist, all_reader, feedback_reader, _monitor_archivist })
    }
}
