// Copyright 2019 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 std::collections::HashMap;

use sdk_metadata::{CpuArchitecture, HostTool, JsonObject};

use crate::app::Result;
use crate::file_provider::{merge_files, FileProvider};
use crate::tarball::{InputTarball, OutputTarball, TarballContent};

impl FileProvider for HostTool {
    fn get_common_files(&self) -> Vec<String> {
        if let Some(files) = self.files.clone() {
            return files;
        }
        Vec::new()
    }

    fn get_arch_files(&self) -> HashMap<CpuArchitecture, Vec<String>> {
        if let Some(files) = self.target_files.clone() {
            return files;
        }
        HashMap::new()
    }
}

pub fn merge_host_tool<F: TarballContent>(
    meta_path: &str,
    base: &impl InputTarball<F>,
    complement: &impl InputTarball<F>,
    output: &mut impl OutputTarball<F>,
) -> Result<()> {
    let base_meta: HostTool = base.get_metadata(meta_path)?;
    let complement_meta: HostTool = complement.get_metadata(meta_path)?;
    merge_files(&base_meta, base, &complement_meta, complement, output)?;

    let mut meta = base_meta.clone();
    if let Some(complement_target_files) = &complement_meta.target_files {
        if let Some(meta_target_files) = &mut meta.target_files {
            for (arch, files) in complement_target_files {
                meta_target_files.insert(arch.clone(), files.to_vec());
            }
        } else {
            meta.target_files = complement_meta.target_files.clone();
        }
    }
    meta.validate()?;
    output.write_json(meta_path, &meta)?;

    Ok(())
}

#[cfg(test)]
mod tests {
    use crate::testing::{MockInputTarball, MockOutputTarball};

    use super::*;

    #[test]
    fn test_merge() {
        let meta = "tools/foobar-meta.json";
        let data = r#"
        {
            "name": "foobar",
            "type": "host_tool",
            "root": "tools",
            "files": [
                "tools/foobar"
            ]
        }
        "#;
        let base = MockInputTarball::new();
        base.add(meta, data);
        base.add("tools/foobar", "I am a tool");
        let complement = MockInputTarball::new();
        complement.add(meta, data);
        complement.add("tools/foobar", "I am a tool");
        let mut output = MockOutputTarball::new();
        merge_host_tool(meta, &base, &complement, &mut output).expect("Should not fail!");
        output.assert_has_file(meta);
        output.assert_has_file("tools/foobar");
    }

    #[test]
    fn test_merge_multiple_architectures() {
        let meta = "tools/foobar-meta.json";
        let base_data = r#"
        {
            "name": "foobar",
            "type": "host_tool",
            "root": "tools",
            "target_files": {
                "x64": [
                    "tools/foobar_x64"
                ]
            }
        }
        "#;
        let complement_data = r#"
        {
            "name": "foobar",
            "type": "host_tool",
            "root": "tools",
            "target_files": {
                "arm64": [
                    "tools/foobar_arm64"
                ]
            }
        }
        "#;
        let base = MockInputTarball::new();
        base.add(meta, base_data);
        base.add("tools/foobar_x64", "I am a tool");
        let complement = MockInputTarball::new();
        complement.add(meta, complement_data);
        complement.add("tools/foobar_arm64", "I am a tool too");
        let mut output = MockOutputTarball::new();
        merge_host_tool(meta, &base, &complement, &mut output).expect("Should not fail!");
        output.assert_has_file(meta);
        output.assert_has_file("tools/foobar_x64");
        output.assert_has_file("tools/foobar_arm64");
        let data = HostTool::new(output.get_content(meta).as_bytes()).unwrap();
        assert!(data.target_files.is_some());
        assert!(data.target_files.unwrap().len() == 2, "Invalid number of architectures");
    }
}
