// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Handles storage of persistent data.

use std::fs::create_dir;
use std::io::Error as IoError;
use std::path::{Path, PathBuf};

use libchromeos::chromeos::{self, get_daemonstore_path};
use libsirenia::storage::{self, FileStorage, Storage};
use sys_util::scoped_path::get_temp_path;
use thiserror::Error as ThisError;

// Export this so dependencies don't need to explicitly depend on libsirenia.
pub use libsirenia::communication::persistence::Scope;

#[derive(ThisError, Debug)]
pub enum Error {
    #[error("failed to retrieve daemonstore path: {0:?}")]
    DaemonstorePath(chromeos::Error),
    #[error("storage path doesn't exist for scope: {0:?}")]
    StoragePathNotExist(Scope),
    #[error("domain path doesn't exist: '{0:?}'")]
    DomainNotExist(String),
    #[error("domain is invalid: '{0}'")]
    InvalidDomain(String),
    #[error("failed to create domain '{0:?}': {1:?}")]
    FailedToCreateDomain(String, IoError),
    #[error("failed to create test scope path '{0:?}': {1:?}")]
    CreateTestPath(String, IoError),
    #[error("failed to create filestorage: '{0:?}'")]
    FileStorage(IoError),
    #[error("failed to write data: '{0:?}'")]
    WriteData(storage::Error),
    #[error("failed to read data: '{0:?}'")]
    ReadData(storage::Error),
}

impl Error {
    pub fn is_unwritten_id(&self) -> bool {
        matches!(
            self,
            Error::DomainNotExist(_) | Error::ReadData(storage::Error::IdNotFound(_))
        )
    }
}

pub type Result<R> = std::result::Result<R, Error>;

/// Check if an error was caused by looking up an entry that was not written yet.
pub fn is_unwritten_id<R>(res: &Result<R>) -> bool {
    if let Err(e) = res {
        e.is_unwritten_id()
    } else {
        false
    }
}

const DAEMON_STORE_NAME: &str = "cronista";
const DEFAULT_SYSTEM_STORAGE_PATH: &str = "/var/lib/cronista";

fn get_system_storage_path() -> PathBuf {
    Path::new(DEFAULT_SYSTEM_STORAGE_PATH).to_path_buf()
}

fn get_session_storage_path() -> Result<PathBuf> {
    get_daemonstore_path(DAEMON_STORE_NAME).map_err(Error::DaemonstorePath)
}

fn get_storage_path(scope: Scope, domain: &str) -> Result<PathBuf> {
    let domain =
        FileStorage::validate_id(domain).map_err(|_| Error::InvalidDomain(domain.to_string()))?;

    let path = match scope {
        Scope::System => get_system_storage_path(),
        Scope::Session => get_session_storage_path()?,
        Scope::Test => get_temp_path(None),
    };
    if !path.exists() {
        return Err(Error::StoragePathNotExist(scope));
    }
    let sub_path = path.join(&domain);
    Ok(sub_path)
}

pub fn initialize_storage() -> Result<()> {
    let test_path = get_temp_path(None);
    if !test_path.is_dir() {
        create_dir(&test_path)
            .map_err(|err| Error::CreateTestPath(test_path.to_string_lossy().to_string(), err))?;
    }
    Ok(())
}

/// Persists the data at the specified location denoted by (scope, domain, identifier).
pub fn persist(scope: Scope, domain: &str, identifier: &str, data: &[u8]) -> Result<()> {
    let path = get_storage_path(scope, domain)?;
    if !path.is_dir() {
        create_dir(&path).map_err(|err| Error::FailedToCreateDomain(domain.to_string(), err))?;
    }
    let mut storage = FileStorage::new(path).map_err(Error::FileStorage)?;
    storage
        .write_raw(identifier, data)
        .map_err(Error::WriteData)
}

/// Retrieves the data from the specified location denoted by (scope, domain, identifier).
pub fn retrieve(scope: Scope, domain: &str, identifier: &str) -> Result<Vec<u8>> {
    let path = get_storage_path(scope, domain)?;
    if !path.is_dir() {
        return Err(Error::DomainNotExist(domain.to_string()));
    }
    let mut storage = FileStorage::new(path).map_err(Error::FileStorage)?;
    storage.read_raw(identifier).map_err(Error::ReadData)
}

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

    use std::fs::File;
    use std::io::Write;
    use std::time::{SystemTime, UNIX_EPOCH};

    use sys_util::scoped_path::ScopedPath;

    const TEST_DOMAIN: &str = "DOMAIN";

    const TEST_ID: &str = "TEST ID";

    fn get_test_value() -> [u8; 8] {
        SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs()
            .to_ne_bytes()
    }

    #[test]
    fn storage_success() {
        let path = ScopedPath::create(get_temp_path(None)).unwrap();
        assert!(path.exists());

        let test_value = get_test_value();
        persist(Scope::Test, TEST_DOMAIN, TEST_ID, &test_value).unwrap();

        let got_value = retrieve(Scope::Test, TEST_DOMAIN, TEST_ID).unwrap();
        assert_eq!(got_value, test_value);
    }

    #[test]
    fn persist_writedata() {
        let path = ScopedPath::create(get_temp_path(None)).unwrap();
        let domain_path = path.join(TEST_DOMAIN);
        create_dir(&domain_path).unwrap();
        create_dir(domain_path.join(TEST_ID)).unwrap();

        let test_value = get_test_value();
        assert!(matches!(
            persist(Scope::Test, TEST_DOMAIN, TEST_ID, &test_value),
            Err(Error::WriteData(_))
        ));
    }

    #[test]
    fn persist_failedtocreatedomain() {
        let path = ScopedPath::create(get_temp_path(None)).unwrap();
        {
            let mut file_at_domain_path = File::create(path.join(TEST_DOMAIN)).unwrap();
            file_at_domain_path.write_all("".as_bytes()).unwrap();
        }

        let test_value = get_test_value();
        assert!(matches!(
            persist(Scope::Test, TEST_DOMAIN, TEST_ID, &test_value),
            Err(Error::FailedToCreateDomain(_, _))
        ));
    }

    #[test]
    fn retrieve_domainnotexist() {
        let path = ScopedPath::create(get_temp_path(None)).unwrap();
        assert!(path.exists());

        assert!(matches!(
            retrieve(Scope::Test, TEST_DOMAIN, TEST_ID),
            Err(Error::DomainNotExist(_))
        ));
    }

    #[test]
    fn retrieve_unwrittenid() {
        let path = ScopedPath::create(get_temp_path(None)).unwrap();
        let domain_path = path.join(TEST_DOMAIN);

        assert!(is_unwritten_id(&retrieve(
            Scope::Test,
            TEST_DOMAIN,
            TEST_ID
        )));

        create_dir(&domain_path).unwrap();

        assert!(is_unwritten_id(&retrieve(
            Scope::Test,
            TEST_DOMAIN,
            TEST_ID
        )));
    }

    #[test]
    fn retrieve_readdata() {
        let path = ScopedPath::create(get_temp_path(None)).unwrap();
        let domain_path = path.join(TEST_DOMAIN);
        create_dir(&domain_path).unwrap();
        create_dir(domain_path.join(TEST_ID)).unwrap();

        assert!(matches!(
            retrieve(Scope::Test, TEST_DOMAIN, TEST_ID),
            Err(Error::ReadData(_))
        ));
    }
}
