// 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.

// Fetches diagnostic data.

use {
    anyhow::{bail, Error},
    diagnostics_reader::{ArchiveReader, DataType},
    log::error,
    triage::DiagnosticData,
    triage::Source,
};

// Selectors for Inspect data must start with this exact string.
const INSPECT_PREFIX: &str = "INSPECT:";
// The capability name for the Inspect reader
const INSPECT_SERVICE_PATH: &str = "/svc/fuchsia.diagnostics.FeedbackArchiveAccessor";

// Durable connection to Archivist
#[derive(Debug)]
pub struct DiagnosticFetcher {
    inspect: InspectFetcher,
}

#[derive(Debug)]
pub struct Selectors {
    pub(crate) inspect_selectors: Vec<String>,
}

impl DiagnosticFetcher {
    pub fn create(selectors: Selectors) -> Result<DiagnosticFetcher, Error> {
        Ok(DiagnosticFetcher { inspect: InspectFetcher::create(selectors.inspect_selectors)? })
    }

    pub async fn get_diagnostics(&mut self) -> Result<Vec<DiagnosticData>, Error> {
        let inspect_data = DiagnosticData::new(
            "inspect.json".to_string(),
            Source::Inspect,
            self.inspect.fetch().await?,
        )?;
        Ok(vec![inspect_data])
    }
}

impl Selectors {
    pub fn new() -> Selectors {
        Selectors { inspect_selectors: Vec::new() }
    }

    pub fn with_inspect_selectors(mut self, selectors: Vec<String>) -> Self {
        self.inspect_selectors.extend(selectors);
        self
    }
}

struct InspectFetcher {
    // If we have no selectors, we don't want to actually fetch anything.
    // (Fetching with no selectors fetches all Inspect data.)
    reader: Option<ArchiveReader>,
}

impl std::fmt::Debug for InspectFetcher {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("InspectFetcher").field("reader", &"opaque-ArchiveReader").finish()
    }
}

impl InspectFetcher {
    pub fn create(selectors: Vec<String>) -> Result<InspectFetcher, Error> {
        if selectors.len() == 0 {
            return Ok(InspectFetcher { reader: None });
        }
        let proxy = match fuchsia_component::client::connect_to_service_at_path::<
            fidl_fuchsia_diagnostics::ArchiveAccessorMarker,
        >(INSPECT_SERVICE_PATH)
        {
            Ok(proxy) => proxy,
            Err(e) => bail!("Failed to connect to Inspect reader: {}", e),
        };
        let reader = ArchiveReader::new().with_archive(proxy);
        let get_inspect = |s: String| -> Option<std::string::String> {
            if &s[..INSPECT_PREFIX.len()] == INSPECT_PREFIX {
                Some(s[INSPECT_PREFIX.len()..].to_string())
            } else {
                error!("All selectors should begin with 'INSPECT:' - '{}'", s);
                None
            }
        };
        let selectors = selectors.into_iter().filter_map(get_inspect);
        let reader = reader.retry_if_empty(false).add_selectors(selectors);
        Ok(InspectFetcher { reader: Some(reader) })
    }

    /// This returns a String in JSON format because that's what TriageLib needs.
    pub async fn fetch(&mut self) -> Result<String, Error> {
        match &self.reader {
            None => Ok("[]".to_string()),
            Some(reader) => {
                // TODO(fxbug.dev/62480): Make TriageLib accept structured data
                Ok(reader.snapshot_raw(DataType::Inspect).await?.to_string())
            }
        }
    }
}
