// Copyright 2018 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 crate::error::Error;
use crate::util;
use crate::util::write_depfile;
use std::fs;
use std::io::{BufRead, BufReader, Write};
use std::path::PathBuf;
use std::str::FromStr;

/// read in the provided list of json files, merge them, and pretty-print the merged result to
/// stdout if output is None or to the provided path if output is Some.
/// Files can be specified in `files`, or in the contents of `fromfile` as line-delimited paths,
/// or both.
/// JSON objects are merged recursively, and if two blobs set the same key an error is returned.
/// JSON arrays are appended together, with duplicate items being removed.
/// If a depfile is provided, also writes the files encountered to the depfile.
pub(crate) fn merge(
    mut files: Vec<PathBuf>,
    output: Option<PathBuf>,
    // If specified, this is a path to newline-delimited `files`
    fromfile: Option<PathBuf>,
    depfile: Option<PathBuf>,
) -> Result<(), Error> {
    if let Some(path) = &fromfile {
        let reader = BufReader::new(fs::File::open(path).map_err(|e| {
            Error::invalid_args(format!("Failed to open --fromfile \"{:?}\": {}", path, e))
        })?);
        for line in reader.lines() {
            match line {
                Ok(value) => files.push(PathBuf::from(value)),
                Err(e) => return Err(Error::invalid_args(format!("Invalid --fromfile: {}", e))),
            }
        }
    }
    if files.is_empty() {
        return Err(Error::invalid_args(format!("no files provided")));
    }

    // If given an aggregated CML file generated using GN metadata, merge all of the included
    // CML objects therein.
    let mut document = cml::parse_one_document(&"{}".to_string(), &PathBuf::from_str("").unwrap())?;
    for file in &files {
        let include_documents = util::read_cml_tolerate_gn_metadata(&file)?;
        for mut d in include_documents.into_iter() {
            document.merge_from(&mut d, &file)?;
        }
    }
    document.canonicalize();

    let json_str = serde_json::to_string_pretty(&document)?;
    if let Some(output_path) = &output {
        util::ensure_directory_exists(output_path)?;
        fs::OpenOptions::new()
            .create(true)
            .truncate(true)
            .write(true)
            .open(output_path)?
            .write_all(json_str.as_bytes())?;
    } else {
        println!("{}", json_str);
    }

    // Write files to depfile
    if let Some(depfile_path) = depfile {
        write_depfile(&depfile_path, output.as_ref(), &files)?;
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;
    use std::fs::File;
    use std::io::{LineWriter, Read};
    use tempfile::TempDir;

    #[test]
    fn test_merge_cml() {
        let tmp_dir = TempDir::new().unwrap();

        let input = vec![
            (tmp_dir.path().join("1.cml"), "{use: [{ protocol: [\"bar\"]}]}"),
            (tmp_dir.path().join("2.cml"), "{use: [{ protocol: [\"foo\", \"bar\"]}]}"),
        ];
        let mut filenames = vec![];
        for (fname, contents) in &input {
            File::create(fname).unwrap().write_all(contents.as_bytes()).unwrap();
            filenames.push(fname.clone());
        }

        let output_file_path = tmp_dir.path().join("output.json");
        merge(filenames, Some(output_file_path.clone()), None, None).expect("failed to merge");

        let mut buffer = String::new();
        File::open(&output_file_path).unwrap().read_to_string(&mut buffer).unwrap();
        let expected_json = json!({
            "use": [
                {"protocol": ["bar", "foo"]},
            ]
        });
        assert_eq!(buffer, format!("{:#}", expected_json));
    }

    #[test]
    fn test_merge_cml_gn_metadata() {
        let tmp_dir = TempDir::new().unwrap();

        let input = vec![
            (
                tmp_dir.path().join("1.cml"),
                "[{use: [{ protocol: [\"bar\"]}]}, {use: [{ protocol: [\"baz\"]}]}]",
            ),
            (tmp_dir.path().join("2.cml"), "[{use: [{ protocol: [\"foo\", \"bar\"]}]}]"),
        ];
        let mut filenames = vec![];
        for (fname, contents) in &input {
            File::create(fname).unwrap().write_all(contents.as_bytes()).unwrap();
            filenames.push(fname.clone());
        }

        let output_file_path = tmp_dir.path().join("output.json");
        merge(filenames, Some(output_file_path.clone()), None, None).expect("failed to merge");

        let mut buffer = String::new();
        File::open(&output_file_path).unwrap().read_to_string(&mut buffer).unwrap();
        let expected_json = json!({
            "use": [
                {"protocol": ["bar", "baz", "foo"]},
            ]
        });
        assert_eq!(buffer, format!("{:#}", expected_json));
    }

    #[test]
    fn test_merge_invalid_json_fails() {
        let tmp_dir = TempDir::new().unwrap();

        let input = vec![
            (tmp_dir.path().join("1.json"), "{\"foo\": 1}"),
            (tmp_dir.path().join("2.json"), "{\"foo\": 1,}"),
        ];
        let mut filenames = vec![];
        for (fname, contents) in &input {
            File::create(fname).unwrap().write_all(contents.as_bytes()).unwrap();
            filenames.push(fname.clone());
        }

        let result = merge(filenames, None, None, None);
        assert!(result.is_err());
    }

    #[test]
    fn test_merge_fromfile() {
        let tmp_dir = TempDir::new().unwrap();

        let input = vec![
            // The first two files will be provided as regular inputs
            (tmp_dir.path().join("1.cml"), "{use: [{ protocol: [\"bar\"]}]}"),
            (tmp_dir.path().join("2.cml"), "{use: [{ protocol: [\"foo\"]}]}"),
            // The third file will be referenced via --fromfile
            (tmp_dir.path().join("3.cml"), "{use: [{ protocol: [\"baz\"]}]}"),
        ];
        for (fname, contents) in &input {
            File::create(fname).unwrap().write_all(contents.as_bytes()).unwrap();
        }
        let mut filenames = vec![];
        for (fname, _) in &input[..2] {
            filenames.push(fname.clone());
        }
        let fromfile_path = tmp_dir.path().join("fromfile");
        let mut fromfile = LineWriter::new(File::create(fromfile_path.clone()).unwrap());
        writeln!(fromfile, "{}", input[2].0.clone().into_os_string().into_string().unwrap())
            .unwrap();

        let output_file_path = tmp_dir.path().join("output.cml");
        merge(filenames, Some(output_file_path.clone()), Some(fromfile_path), None)
            .expect("failed to merge");

        let mut buffer = String::new();
        File::open(&output_file_path).unwrap().read_to_string(&mut buffer).unwrap();
        let expected_json = json!({
            "use": [
                {"protocol": ["bar", "baz", "foo"]},
            ]
        });
        assert_eq!(buffer, format!("{:#}", expected_json));
    }
}
