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

#![deny(missing_docs)]

//! Utility methods and traits used throughout assembly.
mod fast_copy;
mod files;
mod insert_unique;
mod named_map;
mod paths;

pub use fast_copy::fast_copy;
pub use files::{
    BlobfsCompiledPackageDestination, BootfsCompiledPackageDestination, BootfsDestination,
    BootfsPackageDestination, CompiledPackageDestination, Destination, FileEntry,
    PackageDestination, PackageSetDestination, TestCompiledPackageDestination,
};
pub use insert_unique::{
    BTreeMapDuplicateKeyError, DuplicateKeyError, InsertAllUniqueExt, InsertUniqueExt, MapEntry,
};
pub use named_map::{Key as NamedMapKey, NamedMap};
pub use paths::{PathTypeMarker, TypedPathBuf};

use anyhow::{Context as _, Result};
use serde::Serialize;
use std::fs;
use std::fs::File;
use std::io::Read;
use std::path::Path;

/// Read a config file (or really any JSON/JSON5 file) into a instance of type
/// T, with a useful error context if it fails.
pub fn read_config<T>(path: impl AsRef<Path>) -> Result<T>
where
    T: serde::de::DeserializeOwned,
{
    let mut file = File::open(path.as_ref())
        .context(format!("Unable to open file: {}", path.as_ref().display()))?;
    from_reader(&mut file).context(format!("Unable to read file: {}", path.as_ref().display()))
}

/// Serializes the given object to a JSON file.
pub fn write_json_file<T: ?Sized>(json_path: impl AsRef<Path>, value: &T) -> Result<()>
where
    T: Serialize,
{
    let json_path = json_path.as_ref();
    if let Some(parent) = json_path.parent() {
        fs::create_dir_all(parent)
            .with_context(|| format!("cannot create {}", parent.display()))?;
    }
    let file = File::create(json_path)
        .with_context(|| format!("cannot create {}", json_path.display()))?;
    serde_json::to_writer_pretty(&file, &value)
        .with_context(|| format!("cannot serialize {}", json_path.display()))
}

/// Deserialize an instance of type T from an IO stream of JSON or JSON5
pub fn from_reader<R, T>(reader: &mut R) -> Result<T>
where
    R: Read,
    T: serde::de::DeserializeOwned,
{
    let mut data = String::default();
    reader.read_to_string(&mut data).context("Cannot read the config")?;

    // First parse the json5 to a `serde_json::Value`, which handles the syntax
    // differences between json5 and json.
    let value: serde_json::Value =
        serde_json5::from_str(&data).context("Cannot parse the json5 config")?;

    // Dump the Value into a JSON string.
    let json = serde_json::to_string_pretty(&value)?;

    // Re-parse using serde_json, which will throw errors when encountering
    // maps when deserializing unit-type enum variants (serde_json5 doesn't do
    // this).
    // TODO: Remove this series of transformations after the following issue
    // is fixed: https://github.com/google/serde_json5/issues/10
    serde_json::from_str(&json).context("cannot parse the config using serde_json")
}

/// Helper fn to insert into an empty Option, or return an Error.
pub fn set_option_once_or<T, E>(
    opt: &mut Option<T>,
    value: impl Into<Option<T>>,
    e: E,
) -> Result<(), E> {
    set_option_once_or_else(opt, value, || e)
}

/// Helper fn to insert into an empty Option, or return an Error created by a
/// closure.
pub fn set_option_once_or_else<T, E, F: FnOnce() -> E>(
    opt: &mut Option<T>,
    value: impl Into<Option<T>>,
    f: F,
) -> Result<(), E> {
    let value = value.into();
    if value.is_none() {
        Ok(())
    } else {
        if opt.is_some() {
            Err(f())
        } else {
            *opt = value;
            Ok(())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use anyhow::anyhow;
    use serde::Deserialize;
    use serde_json::json;
    use std::io::Cursor;
    use tempfile::TempDir;

    #[derive(Debug, Deserialize, PartialEq)]
    struct MyStruct {
        key1: String,
    }

    #[test]
    fn test_set_option_once() {
        let mut opt = None;

        // should be able to set None on None.
        assert!(
            set_option_once_or(&mut opt, None, anyhow!("an error")).is_ok(),
            "Setting None on None failed"
        );

        // should be able to set Value on None.
        assert!(
            set_option_once_or(&mut opt, Some("some value"), anyhow!("an error")).is_ok(),
            "initial set value failed"
        );
        assert_eq!(opt, Some("some value"));

        // setting None on Some should be a no-op.
        assert!(
            set_option_once_or(&mut opt, None, anyhow!("an error")).is_ok(),
            "Setting None on Some failed"
        );
        assert_eq!(opt, Some("some value"), "Setting None on Some was not a no-op");

        // setting Some on Some should fail.
        assert!(
            set_option_once_or(&mut opt, "other value", anyhow!("an error")).is_err(),
            "Setting Some on Some did not fail"
        );
        assert_eq!(
            opt,
            Some("some value"),
            "Setting Some(other) on Some(value) changed the value with an error"
        );
    }

    #[test]
    fn reader_valid_json5() {
        let json5: String = r#"{key1: "value1",}"#.to_string();
        let mut cursor = Cursor::new(json5);
        let value: MyStruct = from_reader(&mut cursor).unwrap();
        assert_eq!(value.key1, "value1");
    }

    #[test]
    fn reader_invalid_json5() {
        #[derive(Deserialize)]
        #[serde(deny_unknown_fields)]
        struct MyStruct {}
        let json5: String = r#"{key1: "value1",}"#.to_string();
        let mut cursor = Cursor::new(json5);
        let value: Result<MyStruct> = from_reader(&mut cursor);
        assert!(value.is_err());
    }

    #[test]
    fn test_read_config() {
        let json = json!({
            "key1": "value1",
        });
        let file = tempfile::NamedTempFile::new().unwrap();
        serde_json::ser::to_writer(&file, &json).unwrap();

        let value: MyStruct = read_config(file.path()).unwrap();
        let expected: MyStruct = serde_json::from_value(json).unwrap();
        assert_eq!(expected, value);
    }

    #[test]
    fn test_write_json_file() {
        let expected = json!({
            "key1": "value1",
        });
        let temp_dir = TempDir::new().unwrap();
        let path = temp_dir.path().join("config.json");
        write_json_file(&path, &expected).unwrap();

        let actual: serde_json::Value = read_config(path).unwrap();
        assert_eq!(expected, actual);
    }
}
