// 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.

//! Initializers for ICU data files.
//!
//! Use the library by instantiating a `Loader` and keeping a reference to it for as long as you
//! need access to timezone data.  You can do this in your program as many times as needed, and the
//! loader will make sure that the data is loaded before it is first used, and that it is unloaded
//! once no more loaders are live.
//!
//! It is also possible to clone a loader in case you need to pass it along to ensure that timezone
//! data is available.
//!
//! Example use:
//!
//! ```
//! fn basic() {
//!     let _loader = Loader::new().expect("loader is constructed with success");
//!     let _loader2 = Loader::new().expect("second initialization is a no-operation");
//!     let _loader3 = _loader2.clone();  // It is OK to clone a loader and keep it around.
//! }
//! ```

use std::path::PathBuf;

use {
    anyhow::{format_err, Context},
    fuchsia_zircon as zx,
    lazy_static::lazy_static,
    rust_icu_common as icu, rust_icu_ucal as ucal, rust_icu_udata as udata,
    std::{
        borrow::Cow,
        env, fs, io,
        sync::{Arc, Mutex, Weak},
    },
    thiserror::Error,
};

lazy_static! {
    // The storage for the loaded ICU data.  At most one may be loaded at any given time.
    static ref REFCOUNT: Mutex<Weak<PathBuf>> = Mutex::new(Weak::new());
}

// The default location at which to find the ICU data.
// The icudtl.dat is deliberately omitted to conform to the loading
// rules described at:
// https://unicode-org.github.io/icu/userguide/icu_data/#how-data-loading-works
const ICU_DATA_PATH_DEFAULT: &str = "/pkg/data";

/// Minimum expected length of a time zone revision ID (e.g. "2019c").
const MIN_TZ_REVISION_ID_LENGTH: usize = 5;
/// Maximum expected length of a time zone revision ID.
const MAX_TZ_REVISION_ID_LENGTH: usize = 15;

/// Error type returned by `icu_udata`. The individual enum values encode
/// classes of possible errors returned.
#[derive(Error, Debug)]
pub enum Error {
    #[error("[icu_data]: {}", _0)]
    Fail(anyhow::Error),
    /// The operation failed due to an underlying Zircon error.
    #[error("[icu_data]: generic error: {}, details: {:?}", _0, _1)]
    Status(zx::Status, Option<Cow<'static, str>>),
    /// The operation failed due to an IO error.
    #[error("[icu_data]: IO error: {}", _0)]
    IO(io::Error),
    /// The operation failed due to an ICU library error.
    #[error("[icu_data]: ICU error: {}", _0)]
    ICU(icu::Error),
}
impl From<zx::Status> for Error {
    fn from(status: zx::Status) -> Self {
        Error::Status(status, None)
    }
}
impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::IO(err)
    }
}
impl From<anyhow::Error> for Error {
    fn from(err: anyhow::Error) -> Self {
        Error::Fail(err)
    }
}
impl From<icu::Error> for Error {
    fn from(err: icu::Error) -> Self {
        Error::ICU(err)
    }
}

/// Manages the lifecycle of the loaded ICU data.
///
/// `Loader` can be created using `Loader::new` and can be cloned.  For as long as any Loader
/// remains in scope, the ICU data will not be unloaded.
#[derive(Debug, Clone)]
pub struct Loader {
    // The reference here holds the ICU data in memory. It should be held live
    // until the end of the program.
    _refs: Arc<PathBuf>,
}
// Loader is OK to be sent to threads.
unsafe impl Sync for Loader {}

impl Loader {
    /// Initializes the ICU dynamic timezone data, based on the default resource directory.
    ///
    /// The caller should create a `Loader` very early on in the lifetime of the program, and keep
    /// instances of `Loader` alive until the ICU data is needed.  You can make as many `Loader`
    /// objects as you need.  The data will be unloaded only after the last of them leaves scope.
    pub fn new() -> Result<Self, Error> {
        Self::new_with_optional_tz_resources(None, None)
    }

    /// Initializes ICU data, loading time zone resources from the supplied `path`.
    ///
    /// See documentation for `new` for calling constraints.
    pub fn new_with_tz_resource_path(tzdata_dir_path: &str) -> Result<Self, Error> {
        Self::new_with_optional_tz_resources(Some(tzdata_dir_path), None)
    }

    /// Initializes ICU data, loading time zone resources from the supplied `path` and validating
    /// the time zone revision ID against the ID contained in the file at `revision_file_path`.
    ///
    /// See documentation for `new` for calling constraints.
    pub fn new_with_tz_resources_and_validation(
        tzdata_dir_path: &str,
        tz_revision_file_path: &str,
    ) -> Result<Self, Error> {
        Self::new_with_optional_tz_resources(Some(tzdata_dir_path), Some(tz_revision_file_path))
    }

    // Ensures that all calls to create a `Loader` go through the same code path.
    fn new_with_optional_tz_resources(
        tzdata_dir_path: Option<&str>,
        tz_revision_file_path: Option<&str>,
    ) -> Result<Self, Error> {
        // The lock contention should not be an issue.  Only a few calls (single digits) to this
        // function are expected.  So we take a write lock immmediately.
        let mut l = REFCOUNT.lock().expect("refcount lock acquired");
        match l.upgrade() {
            Some(_refs) => Ok(Loader { _refs }),
            None => {
                // Load up the TZ files directory.
                if let Some(p) = tzdata_dir_path {
                    let for_path = fs::File::open(p)
                        .map_err(|e| Error::Fail(format_err!("io error: {}", e)))
                        .with_context(|| format!("error while opening: {:?}", &tzdata_dir_path))?;
                    let meta = for_path
                        .metadata()
                        .with_context(|| format!("while getting metadata for: {:?}", &p))?;
                    if !meta.is_dir() {
                        return Err(Error::Fail(format_err!("not a directory: {}", p)));
                    }
                    // This is the default API used to configure the ICU library, so we are
                    // just using it here.  Even though it is not a preferred way to configure
                    // Fuchsia programs.
                    // Further, we want to load the same ICU data for all programs that need this
                    // file.
                    env::set_var("ICU_TIMEZONE_FILES_DIR", p);
                }

                // Read ICU data file from the filesystem. The ICU library should
                // take care to load only the needed parts, since the entire common
                // data file is fairly large.
                let path = PathBuf::from(ICU_DATA_PATH_DEFAULT);
                udata::set_data_directory(&path);
                let _refs = Arc::new(path);
                Self::validate_revision(tz_revision_file_path)?;
                (*l) = Arc::downgrade(&_refs);
                Ok(Loader { _refs })
            }
        }
    }

    fn validate_revision(tz_revision_file_path: Option<&str>) -> Result<(), Error> {
        match tz_revision_file_path {
            None => Ok(()),
            Some(tz_revision_file_path) => {
                let expected_revision_id = std::fs::read_to_string(tz_revision_file_path)
                    .with_context(|| {
                        format!("could not read file: {:?}", &tz_revision_file_path)
                    })?;
                if !(MIN_TZ_REVISION_ID_LENGTH..=MAX_TZ_REVISION_ID_LENGTH)
                    .contains(&expected_revision_id.len())
                {
                    return Err(Error::Status(
                        zx::Status::IO_DATA_INTEGRITY,
                        Some(
                            format!(
                                "invalid revision ID in {}: {}",
                                tz_revision_file_path, expected_revision_id
                            )
                            .into(),
                        ),
                    ));
                }

                let actual_revision_id = ucal::get_tz_data_version().with_context(|| {
                    format!("while getting data version from: {:?}", &tz_revision_file_path)
                })?;
                if expected_revision_id != actual_revision_id {
                    return Err(Error::Status(
                        zx::Status::IO_DATA_INTEGRITY,
                        Some(
                            format!(
                                "expected revision ID {} but got {}",
                                expected_revision_id, actual_revision_id
                            )
                            .into(),
                        ),
                    ));
                }

                Ok(())
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use {super::*, assert_matches::assert_matches, rust_icu_uenum as uenum};

    // [START loader_example]
    #[test]
    fn initialization() {
        let _loader = Loader::new().expect("loader is constructed with success");
        let _loader2 = Loader::new().expect("loader is just fine with a second initialization");
        let tz: String = uenum::open_time_zones().unwrap().take(1).map(|e| e.unwrap()).collect();
        assert_eq!(tz, "ACT");
        // The library will be cleaned up after the last of the loaders goes out of scope.
    }

    #[test]
    fn you_can_also_clone_loaders() {
        let _loader = Loader::new().expect("loader is constructed with success");
        let _loader2 = Loader::new().expect("loader is just fine with a second initialization");
        let _loader3 = _loader2.clone();
        let tz: String = uenum::open_time_zones().unwrap().take(1).map(|e| e.unwrap()).collect();
        assert_eq!(tz, "ACT");
    }

    #[test]
    fn two_initializations_in_a_row() {
        {
            let _loader = Loader::new().expect("loader is constructed with success");
            let tz: String =
                uenum::open_time_zones().unwrap().take(1).map(|e| e.unwrap()).collect();
            assert_eq!(tz, "ACT");
        }
        {
            let _loader2 = Loader::new().expect("loader is just fine with a second initialization");
            let tz: String =
                uenum::open_time_zones().unwrap().take(1).map(|e| e.unwrap()).collect();
            assert_eq!(tz, "ACT");
        }
    }
    // [END loader_example]

    #[test]
    fn test_tz_res_loading_without_validation() -> Result<(), Error> {
        let _loader = Loader::new().expect("loader is constructed with success");
        let tz: String = uenum::open_time_zones()?.take(1).map(|e| e.unwrap()).collect();
        assert_eq!(tz, "ACT");
        Ok(())
    }

    #[test]
    fn test_tz_res_loading_with_validation_valid() -> Result<(), Error> {
        let _loader = Loader::new_with_tz_resources_and_validation(
            "/pkg/data/tzdata/icu/44/le",
            "/pkg/data/tzdata/revision.txt",
        )
        .expect("loader is constructed successfully");
        let tz: String = uenum::open_time_zones()?.take(1).map(|e| e.unwrap()).collect();
        assert_eq!(tz, "ACT");
        Ok(())
    }

    #[test]
    fn test_tz_res_loading_with_validation_invalid() -> Result<(), Error> {
        let result = Loader::new_with_tz_resources_and_validation(
            "/pkg/data/tzdata/icu/44/le",
            "/pkg/data/test_inconsistent_revision.txt",
        );
        let err = result.unwrap_err();
        assert_matches!(err, Error::Status(zx::Status::IO_DATA_INTEGRITY, Some(_)));
        Ok(())
    }
}
