// 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::{bail, Error};
use fuchsia_triage::{ActionTagDirective, DiagnosticData, ParseResult, Source};
use std::collections::HashMap;
use std::fs;
use std::path::Path;

// Third field is whether the file is required.
const SNAPSHOT_FILES: [(&str, Source, bool); 5] = [
    ("inspect.json", Source::Inspect, true),
    ("log.kernel.txt", Source::Klog, false),
    ("log.system.txt", Source::Syslog, false),
    ("log.system.previous_boot.txt", Source::Bootlog, false),
    ("annotations.json", Source::Annotations, false),
];

pub fn diagnostics_from_directory(directory: &Path) -> Result<Vec<DiagnosticData>, Error> {
    SNAPSHOT_FILES
        .iter()
        .map(|(name, source, required)| diagnostic_from_file(directory, name, source, required))
        .collect::<Result<Vec<_>, _>>()
}

fn diagnostic_from_file(
    directory: &Path,
    file_name: &str,
    source: &Source,
    required: &bool,
) -> Result<DiagnosticData, Error> {
    let file_path = directory.join(file_name).into_os_string().to_string_lossy().to_string();
    let contents = match fs::read_to_string(&file_path) {
        Ok(contents) => contents,
        Err(_) => {
            if *required {
                bail!("Couldn't read file '{}' to string", file_path);
            } else {
                return Ok(DiagnosticData::new_empty(file_path, *source));
            }
        }
    };
    DiagnosticData::new(file_path, *source, contents)
}

pub fn config_from_files<T: AsRef<Path>>(
    config_files: &[T],
    action_tag_directive_from_tags: &ActionTagDirective,
) -> Result<ParseResult, Error> {
    let mut config_file_map: HashMap<String, String> = HashMap::new();
    for file_name in config_files {
        let file_name = file_name.as_ref();
        let file_data = match fs::read_to_string(file_name) {
            Ok(data) => data,
            Err(e) => {
                bail!("Couldn't read config file '{}' to string, {}", file_name.display(), e);
            }
        };

        match serde_json::from_str::<serde_json::Value>(&file_data) {
            // This file looks like a bundle.
            // Bundles are JSON with a "files" key containing name => content
            // mappings.
            Ok(serde_json::Value::Object(file_object)) if file_object.contains_key("files") => {
                match file_object.get("files").unwrap() {
                    serde_json::Value::Object(files) => {
                        for (name, content) in files {
                            match content {
                                serde_json::Value::String(content) => {
                                    config_file_map.insert(name.to_string(), content.to_string());
                                }
                                _ => {
                                    bail!("File {} looks like a bundle, but key {} must contain a string.", file_name.display(), name);
                                }
                            }
                        }
                    }
                    _ => {
                        bail!(
                            "File {} looks like a bundle, but key 'files' is not an object.",
                            file_name.display()
                        );
                    }
                }
            }
            // The file does not look like a bundle.
            // Get the base name of the file as the namesapce, and add it to the config file set.
            _ => {
                let namespace = base_name(file_name)?;
                config_file_map.insert(namespace, file_data);
            }
        }
    }

    ParseResult::new(&config_file_map, &action_tag_directive_from_tags)
}

fn base_name(path: &Path) -> Result<String, Error> {
    if let Some(s) = path.file_stem() {
        if let Some(s) = s.to_str() {
            return Ok(s.to_owned());
        }
    }
    bail!("Bad path {} - can't find file_stem", path.display())
}

#[cfg(test)]
mod test {
    use super::*;

    #[fuchsia::test]
    fn base_name_works() -> Result<(), Error> {
        assert_eq!(base_name(Path::new("foo/bar/baz.ext"))?, "baz".to_string());
        Ok(())
    }
}
