// 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};
use glob::glob;
use persistence_config::{ServiceName, Tag};
use serde::{ser::SerializeMap, Serialize, Serializer};
use serde_json::Value;
use std::{collections::HashMap, fs};
use tracing::{info, warn};

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

pub(crate) struct PersistSchema {
    pub timestamps: Timestamps,
    pub payload: PersistPayload,
}

pub(crate) enum PersistPayload {
    Data(PersistData),
    Error(String),
}

pub(crate) struct PersistData {
    pub data_length: usize,
    pub entries: HashMap<String, Value>,
}

#[derive(Clone, Serialize)]
pub(crate) struct Timestamps {
    pub before_monotonic: i64,
    pub before_utc: i64,
    pub after_monotonic: i64,
    pub after_utc: i64,
}

// Keys for JSON per-tag metadata to be persisted and published
const TIMESTAMPS_KEY: &str = "@timestamps";
const SIZE_KEY: &str = "@persist_size";
const ERROR_KEY: &str = ":error";
const ERROR_DESCRIPTION_KEY: &str = "description";

impl Serialize for PersistSchema {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match &self.payload {
            PersistPayload::Data(data) => {
                let mut s = serializer.serialize_map(Some(data.entries.len() + 2))?;
                s.serialize_entry(TIMESTAMPS_KEY, &self.timestamps)?;
                s.serialize_entry(SIZE_KEY, &data.data_length)?;
                for (k, v) in data.entries.iter() {
                    s.serialize_entry(k, v)?;
                }
                s.end()
            }
            PersistPayload::Error(error) => {
                let mut s = serializer.serialize_map(Some(2))?;
                s.serialize_entry(TIMESTAMPS_KEY, &self.timestamps)?;
                s.serialize_entry(ERROR_KEY, &ErrorHelper(&error))?;
                s.end()
            }
        }
    }
}

impl PersistSchema {
    pub(crate) fn error(timestamps: Timestamps, description: String) -> Self {
        Self { timestamps, payload: PersistPayload::Error(description) }
    }
}

struct ErrorHelper<'a>(&'a str);

impl<'a> Serialize for ErrorHelper<'a> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut s = serializer.serialize_map(Some(1))?;
        s.serialize_entry(ERROR_DESCRIPTION_KEY, self.0)?;
        s.end()
    }
}

// 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(crate) fn write(service_name: &ServiceName, tag: &Tag, data: &PersistSchema) {
    // /cache/ may be deleted any time. It's OK to try to create CURRENT_PATH if it already exists.
    let path = format!("{}/{}", CURRENT_PATH, service_name);
    fs::create_dir_all(&path)
        .map_err(|e| warn!("Could not create directory {}: {:?}", path, e))
        .ok();
    let data = match serde_json::to_string(data) {
        Ok(data) => data,
        Err(e) => {
            warn!("Could not serialize data - unexpected error {e}");
            return;
        }
    };
    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(https://fxbug.dev/42150693): 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)
}
