// 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::cell::RefCell;
use std::collections::HashMap;

use sdk_metadata::JsonObject;

use crate::app::{Error, Result};
use crate::tarball::{InputTarball, OutputTarball, TarballContent};

impl TarballContent for String {
    fn is_identical(&self, other: &String) -> Result<bool> {
        Ok(self == other)
    }
}

#[derive(Clone)]
pub struct MockInputTarball {
    files: RefCell<HashMap<String, String>>,
}

impl MockInputTarball {
    pub fn new() -> MockInputTarball {
        MockInputTarball { files: RefCell::new(HashMap::new()) }
    }

    pub fn add(&self, path: &str, content: &str) {
        assert!(
            self.files.borrow_mut().insert(path.to_owned(), content.to_owned()).is_none(),
            "Path already added: {}",
            path
        );
    }
}

impl InputTarball<String> for MockInputTarball {
    fn get_file<R>(&self, path: &str, reader: R) -> Result<()>
    where
        R: FnOnce(&mut String) -> Result<()>,
    {
        self.files
            .borrow_mut()
            .get_mut(path)
            .ok_or_else(|| Error::ArchiveFileNotFound { name: path.to_owned() })
            .map(|file_path| -> Result<()> { reader(file_path) })?
    }

    fn get_metadata<T: JsonObject>(&self, path: &str) -> Result<T> {
        let mut contents = String::new();
        self.get_file(path, |value| {
            contents.push_str(value);
            Ok(())
        })?;
        T::new(contents.as_bytes())
    }
}

pub struct MockOutputTarball {
    files: HashMap<String, String>,
}

impl MockOutputTarball {
    pub fn new() -> MockOutputTarball {
        MockOutputTarball { files: HashMap::new() }
    }

    pub fn assert_has_file(&self, path: &str) {
        assert!(self.files.contains_key(path), "File not found: {}", path);
    }

    pub fn get_content(&self, path: &str) -> &String {
        self.assert_has_file(path);
        self.files.get(path).unwrap()
    }
}

impl OutputTarball<String> for MockOutputTarball {
    fn write_json<T: JsonObject>(&mut self, path: &str, content: &T) -> Result<()> {
        self.write_file(path, &mut content.to_string().unwrap())
    }

    fn write_file(&mut self, path: &str, file: &mut String) -> Result<()> {
        assert!(self.files.insert(path.to_owned(), file.clone()).is_none());
        Ok(())
    }
}

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

    #[test]
    fn test_input_get() {
        let tarball = MockInputTarball::new();
        let path = "foo/bar.json";
        let content = "hello world";
        tarball.add(path, content);
        tarball
            .get_file(path, |file_content| {
                assert_eq!(file_content, content);
                Ok(())
            })
            .unwrap();
    }

    #[test]
    fn test_input_get_nonexistent() {
        let tarball = MockInputTarball::new();
        let path = "foo/bar.json";
        assert!(tarball
            .get_file(path, |_file_content| {
                assert!(false, "Should not have been called");
                Ok(())
            })
            .is_err());
    }

    #[test]
    #[should_panic]
    fn test_input_double_add() {
        let tarball = MockInputTarball::new();
        let path = "foo/bar.json";
        let content = "hello world";
        tarball.add(path, content);
        tarball.add(path, content);
    }

    #[test]
    fn test_output_assert() {
        let mut tarball = MockOutputTarball::new();
        let path = "foo/bar.json";
        let mut content = "hello world".to_owned();
        tarball.write_file(path, &mut content).unwrap();
        tarball.assert_has_file(path);
    }

    #[test]
    #[should_panic]
    fn test_output_assert_nonexistent() {
        let tarball = MockOutputTarball::new();
        let path = "foo/bar.json";
        tarball.assert_has_file(path);
    }

    #[test]
    #[should_panic]
    fn test_output_double_write() {
        let mut tarball = MockOutputTarball::new();
        let path = "foo/bar.json";
        let mut content = "hello world".to_owned();
        tarball.write_file(path, &mut content).unwrap();
        tarball.write_file(path, &mut content).unwrap();
    }
}
