// 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 {
    anyhow::{anyhow, Context as _},
    fuchsia_merkle::Hash,
    fuchsia_syslog::fx_log_err,
    serde::{Deserialize, Serialize},
    std::{
        fs::{self, File},
        io,
        path::PathBuf,
    },
};

pub trait LastUpdateStorage {
    fn load(&self) -> Option<Hash>;
    fn store(&self, update: &Hash);
}

pub struct LastUpdateStorageFile {
    pub data_dir: PathBuf,
}

const LAST_UPDATE_FILENAME: &str = "last_update.json";
const LAST_UPDATE_FILENAME_PART: &str = "last_update.json.part";

impl LastUpdateStorage for LastUpdateStorageFile {
    fn load(&self) -> Option<Hash> {
        self.load_impl().unwrap_or_else(|e| {
            fx_log_err!("error loading last_update.json: {:#}", anyhow!(e));
            None
        })
    }
    fn store(&self, update: &Hash) {
        self.store_impl(update).unwrap_or_else(|e| {
            fx_log_err!("error storing last_update info, continuing anyway; {:#}", anyhow!(e));
        })
    }
}
impl LastUpdateStorageFile {
    fn load_impl(&self) -> Result<Option<Hash>, anyhow::Error> {
        let open_result = File::open(self.data_dir.join(LAST_UPDATE_FILENAME));
        if let Err(e) = &open_result {
            if e.kind() == io::ErrorKind::NotFound {
                return Ok(None);
            }
        }
        let file = open_result.context("opening last update file")?;
        let value: StorageFormat =
            serde_json::from_reader(file).context("reading last update file")?;
        let StorageFormat::Version1(v1) = value;
        let hash =
            v1.update_package_merkle.parse::<Hash>().context("parsing update_package_merkle")?;
        Ok(Some(hash))
    }
    fn store_impl(&self, update: &Hash) -> Result<(), anyhow::Error> {
        let wrapped =
            StorageFormat::Version1(StorageFormatV1 { update_package_merkle: update.to_string() });
        let part_filename = self.data_dir.join(LAST_UPDATE_FILENAME_PART);
        {
            let file = File::create(&part_filename).context("opening last update file")?;
            serde_json::to_writer(&file, &wrapped).context("writing last update file")?;
            file.sync_all().context("sync last update file")?;
        }
        fs::rename(part_filename, self.data_dir.join(LAST_UPDATE_FILENAME))
            .context("swap last update file into place")?;
        Ok(())
    }
}

#[derive(Deserialize, Serialize)]
#[serde(tag = "version", content = "content", deny_unknown_fields)]
enum StorageFormat {
    #[serde(rename = "1")]
    Version1(StorageFormatV1),
}

#[derive(Deserialize, Serialize)]
struct StorageFormatV1 {
    update_package_merkle: String,
}

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

    lazy_static! {
        static ref EXAMPLE_UPDATE_HASH: Hash = [0x22; 32].into();
    }

    #[test]
    fn test_load_works() {
        let tempdir = TempDir::new().expect("create tempdir");
        fs::write(
            tempdir.path().join("last_update.json"),
            r#"{"version":"1","content":{"update_package_merkle":"2222222222222222222222222222222222222222222222222222222222222222"}}"#,
        )
        .expect("write last_update.json");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        assert_eq!(storage.load(), Some(*EXAMPLE_UPDATE_HASH));
    }

    #[test]
    fn test_load_without_file_returns_none() {
        let tempdir = TempDir::new().expect("create tempdir");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        assert_eq!(storage.load(), None);
    }

    #[test]
    fn test_load_impl_without_file_returns_none() {
        let tempdir = TempDir::new().expect("create tempdir");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        // We don't want it to print a log if the file isn't found, so it should return Ok(None) instead of an error.
        assert_eq!(storage.load_impl().map_err(|e| e.to_string()), Ok(None));
    }

    #[test]
    fn test_load_with_invalid_file_returns_none() {
        let tempdir = TempDir::new().expect("create tempdir");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        fs::write(
            tempdir.path().join("last_update.json"),
            r#""2222222222222222222222222222222222222222222222222222222222222222""#,
        )
        .expect("write last_update.json");

        assert_eq!(storage.load(), None);
    }

    #[test]
    fn test_store_works() {
        let tempdir = TempDir::new().expect("create tempdir");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        storage.store(&*EXAMPLE_UPDATE_HASH);
        let data = fs::read(tempdir.path().join("last_update.json")).expect("read file");
        let parsed: serde_json::Value = serde_json::from_slice(&data).expect("parse json");
        assert_eq!(
            parsed,
            json!({
                "version": "1",
                "content": {
                    "update_package_merkle": "2222222222222222222222222222222222222222222222222222222222222222"
                }
            })
        )
    }

    #[test]
    fn test_store_roundtrip() {
        let tempdir = TempDir::new().expect("create tempdir");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        storage.store(&*EXAMPLE_UPDATE_HASH);
        assert_eq!(storage.load().expect("a stored value"), *EXAMPLE_UPDATE_HASH);
    }

    #[test]
    fn test_store_overwrite() {
        let tempdir = TempDir::new().expect("create tempdir");
        let storage = LastUpdateStorageFile { data_dir: tempdir.path().into() };
        storage.store(&[0x33; 32].into());
        storage.store(&*EXAMPLE_UPDATE_HASH);
        assert_eq!(storage.load().expect("a stored value"), *EXAMPLE_UPDATE_HASH);
    }
}
