// 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::{format_err, Error},
    glob::glob,
    std::fs,
    tracing::{info, warn},
};

const CURRENT_PATH: &str = "/cache/current";
const PREVIOUS_PATH: &str = "/cache/previous";

// Throw away stuff from two boots ago. Move stuff in the "current"
// directory to the "previous" directory.
pub fn shuffle_at_boot() {
    // These may fail if /cache was wiped. This is WAI and should not signal an error.
    fs::remove_dir_all(PREVIOUS_PATH)
        .map_err(|e| info!("Could not delete {}: {:?}", PREVIOUS_PATH, e))
        .ok();
    fs::rename(CURRENT_PATH, PREVIOUS_PATH)
        .map_err(|e| info!("Could not move {} to {}: {:?}", CURRENT_PATH, PREVIOUS_PATH, e))
        .ok();
}

// Write a VMO's contents to the appropriate file.
pub fn write(service_name: &str, tag: &str, data: &str) {
    // /cache/ may be deleted any time. It's OK to try to create CURRENT_PATH if it alreay exists.
    let path = format!("{}/{}", CURRENT_PATH, service_name);
    fs::create_dir_all(&path)
        .map_err(|e| warn!("Could not create directory {}: {:?}", path, e))
        .ok();
    fs::write(&format!("{}/{}", path, tag), data)
        .map_err(|e| warn!("Could not write file {}/{}: {:?}", path, tag, e))
        .ok();
}

// All the names in the previous-boot directory.
// TODO(fxbug.dev/71350): If this gets big, use Lazy Inspect.
pub(crate) fn remembered_data() -> Result<Vec<(String, Vec<(String, String)>)>, Error> {
    // Counter for number of tags successfully retrieved. If no persisted tags were
    // retrieved, this method returns an error.
    let mut tags_retrieved = 0;

    let mut service_entries = Vec::new();
    // Create an iterator over all subdirectories of /cache/previous
    // which contains persisted data from the last boot.
    for service_path in glob(&format!("{}/*", PREVIOUS_PATH))
        .map_err(|e| format_err!("Failed to read previous-path glob pattern: {:?}", e))?
    {
        match service_path {
            Err(e) => {
                // If our glob pattern was valid, but we encountered glob errors while iterating, just warn
                // since there may still be some persisted metrics.
                warn!(
                    "Encountered GlobError; contents could not be read to determine if glob pattern was matched: {:?}",
                    e
                )
            }
            Ok(path) => {
                if let Some(name) = path.file_name() {
                    let service_name = name.to_string_lossy().to_string();
                    let mut tag_entries = Vec::new();
                    for tag_path in
                        glob(&format!("{}/{}/*", PREVIOUS_PATH, service_name)).map_err(|e| {
                            format_err!(
                                "Failed to read previous service persistence pattern: {:?}",
                                e
                            )
                        })?
                    {
                        match tag_path {
                            Ok(path) => {
                                if let Some(tag_name) = path.file_name() {
                                    let tag_name = tag_name.to_string_lossy().to_string();
                                    match fs::read(path.clone()) {
                                        Ok(text) => {
                                            // TODO(cphoenix): We want to encode failures at retrieving persisted
                                            // metrics in the inspect hierarchy so clients know why their data is
                                            // missing.
                                            match std::str::from_utf8(&text) {
                                                Ok(contents) => {
                                                    tags_retrieved += 1;

                                                    tag_entries
                                                        .push((tag_name, contents.to_owned()));
                                                }
                                                Err(e) => {
                                                    warn!(
                                                        "Failed to parse persisted bytes at path: {:?} into text: {:?}",
                                                        path, e
                                                    );
                                                }
                                            }
                                        }
                                        Err(e) => {
                                            warn!(
                                            "Failed to retrieve text persisted at path: {:?}: {:?}",
                                            path, e
                                        );
                                        }
                                    }
                                }
                            }
                            Err(e) => {
                                // If our glob pattern was valid, but we encountered glob errors while iterating, just warn
                                // since there may still be some persisted metrics.
                                warn!(
                                        "Encountered GlobError; contents could not be read to determine if glob pattern was matched: {:?}",
                                        e
                                    )
                            }
                        }
                    }
                    service_entries.push((service_name, tag_entries));
                }
            }
        };
    }

    if tags_retrieved == 0 {
        info!("No persisted data was successfully retrieved.");
    }

    Ok(service_entries)
}
