// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! # Rust implementation of the `uenum.h` C API header for ICU.

use {
    rust_icu_common as common, rust_icu_sys as sys,
    rust_icu_sys::*,
    std::{convert::TryFrom, ffi, str},
};

/// Rust wrapper for the UEnumeration iterator.
///
/// Implements `UEnumeration`
#[derive(Debug)]
pub struct Enumeration {
    // The raw underlying character array, in case the underlying char array is
    // owned by this enumeration.
    raw: Option<common::CStringVec>,

    // Internal low-level representation of the enumeration.  The internal
    // representation relies on `raw` and `len` above and must live at most as
    // long.
    rep: *mut sys::UEnumeration,
}

impl Enumeration {
    /// Internal representation, for ICU4C methods that require it.
    pub fn repr(&mut self) -> *mut sys::UEnumeration {
        self.rep
    }

    /// Creates an empty `Enumeration`.
    pub fn empty() -> Self {
        Enumeration::try_from(&vec![][..]).unwrap()
    }
}

impl Default for Enumeration {
    fn default() -> Self {
        Self::empty()
    }
}

/// Creates an enumeration iterator from a vector of UTF-8 strings.
impl TryFrom<&[&str]> for Enumeration {
    type Error = common::Error;

    /// Constructs an enumeration from a string slice.
    ///
    /// Implements `uenum_openCharStringsEnumeration`
    fn try_from(v: &[&str]) -> Result<Enumeration, common::Error> {
        let raw = common::CStringVec::new(v)?;
        let mut status = common::Error::OK_CODE;
        let rep: *mut sys::UEnumeration = unsafe {
            versioned_function!(uenum_openCharStringsEnumeration)(
                raw.as_c_array(),
                raw.len() as i32,
                &mut status,
            )
        };
        common::Error::ok_or_warning(status)?;
        // rep should not be null without an error set, but:
        // https://unicode-org.atlassian.net/browse/ICU-20918
        assert!(!rep.is_null());
        Ok(Enumeration {
            rep: rep,
            raw: Some(raw),
        })
    }
}

impl Drop for Enumeration {
    /// Drops the Enumeration, deallocating its internal representation hopefully correctly.
    ///
    /// Implements `uenum_close`
    fn drop(&mut self) {
        unsafe { versioned_function!(uenum_close)(self.rep) };
    }
}

impl Iterator for Enumeration {
    type Item = Result<String, common::Error>;

    /// Yields the next element stored in the enumeration.
    ///
    /// Implements `uenum_next`
    fn next(&mut self) -> Option<Self::Item> {
        let mut len: i32 = 0;
        let mut status = common::Error::OK_CODE;
        // Requires that self.rep is a valid pointer to a sys::UEnumeration.
        assert!(!self.rep.is_null());
        let raw = unsafe { versioned_function!(uenum_next)(self.rep, &mut len, &mut status) };
        if raw.is_null() {
            // No more elements to iterate over.
            return None;
        }
        let result = common::Error::ok_or_warning(status);
        match result {
            Ok(()) => {
                assert!(!raw.is_null());
                // Requires that raw is a valid pointer to a C string.
                let cstring = unsafe { ffi::CStr::from_ptr(raw) }; // Borrowing
                Some(Ok(cstring
                    .to_str()
                    .expect("could not convert to string")
                    .to_string()))
            }
            Err(e) => Some(Err(e)),
        }
    }
}

impl Enumeration {
    /// Constructs an [Enumeration] from a raw pointer.
    ///
    /// **DO NOT USE THIS FUNCTION UNLESS THERE IS NO OTHER CHOICE!**
    ///
    /// We tried to keep this function hidden to avoid the
    /// need to have a such a powerful unsafe function in the
    /// public API.  It worked up to a point for free functions.
    ///
    /// It no longer works on high-level methods that return
    /// enumerations, since then we'd need to depend on them to
    /// create an [Enumeration].
    #[doc(hidden)]
    pub unsafe fn from_raw_parts(
        raw: Option<common::CStringVec>,
        rep: *mut sys::UEnumeration,
    ) -> Enumeration {
        Enumeration { raw, rep }
    }
}

#[doc(hidden)]
/// Implements `ucal_openCountryTimeZones`.
// This should be in the `ucal` crate, but not possible because of the raw enum initialization.
// Tested in `ucal`.
pub fn ucal_open_country_time_zones(country: &str) -> Result<Enumeration, common::Error> {
    let mut status = common::Error::OK_CODE;
    let asciiz_country = ffi::CString::new(country)?;
    // Requires that the asciiz country be a pointer to a valid C string.
    let raw_enum = unsafe {
        assert!(common::Error::is_ok(status));
        versioned_function!(ucal_openCountryTimeZones)(asciiz_country.as_ptr(), &mut status)
    };
    common::Error::ok_or_warning(status)?;
    Ok(Enumeration {
        raw: None,
        rep: raw_enum,
    })
}

#[doc(hidden)]
/// Implements `ucal_openTimeZoneIDEnumeration`
// This should be in the `ucal` crate, but not possible because of the raw enum initialization.
// Tested in `ucal`.
pub fn ucal_open_time_zone_id_enumeration(
    zone_type: sys::USystemTimeZoneType,
    region: Option<&str>,
    raw_offset: Option<i32>,
) -> Result<Enumeration, common::Error> {
    let mut status = common::Error::OK_CODE;
    let asciiz_region = match region {
        None => None,
        Some(region) => Some(ffi::CString::new(region)?),
    };
    let mut repr_raw_offset: i32 = raw_offset.unwrap_or_default();

    // asciiz_region should be a valid asciiz pointer. raw_offset is an encoding
    // of an optional value by a C pointer.
    let raw_enum = unsafe {
        assert!(common::Error::is_ok(status));
        versioned_function!(ucal_openTimeZoneIDEnumeration)(
            zone_type,
            // Note that for the string pointer to remain valid, we must borrow the CString from
            // asciiz_region, not move the CString out.
            match &asciiz_region {
                Some(asciiz_region) => asciiz_region.as_ptr(),
                None => std::ptr::null(),
            },
            match raw_offset {
                Some(_) => &mut repr_raw_offset,
                None => std::ptr::null_mut(),
            },
            &mut status,
        )
    };
    common::Error::ok_or_warning(status)?;
    Ok(Enumeration {
        raw: None,
        rep: raw_enum,
    })
}

#[doc(hidden)]
/// Opens a list of available time zones.
///
/// Implements `ucal_openTimeZones`
// This should be in the `ucal` crate, but not possible because of the raw enum initialization.
// Tested in `ucal`.
pub fn open_time_zones() -> Result<Enumeration, common::Error> {
    let mut status = common::Error::OK_CODE;
    let raw_enum = unsafe {
        assert!(common::Error::is_ok(status));
        versioned_function!(ucal_openTimeZones)(&mut status)
    };
    common::Error::ok_or_warning(status)?;
    Ok(Enumeration {
        raw: None,
        rep: raw_enum,
    })
}

#[doc(hidden)]
/// Implements `uloc_openKeywords`.
// This should be in the `uloc` crate, but this is not possible because of the raw enum
// initialization. Tested in `uloc`.
pub fn uloc_open_keywords(locale: &str) -> Result<Enumeration, common::Error> {
    let mut status = common::Error::OK_CODE;
    let asciiz_locale = ffi::CString::new(locale)?;
    let raw_enum = unsafe {
        assert!(common::Error::is_ok(status));
        versioned_function!(uloc_openKeywords)(asciiz_locale.as_ptr(), &mut status)
    };
    common::Error::ok_or_warning(status)?;
    // "No error but null" means that there are no keywords
    if raw_enum.is_null() {
        Ok(Enumeration::empty())
    } else {
        Ok(Enumeration {
            raw: None,
            rep: raw_enum,
        })
    }
}

#[cfg(test)]
mod tests {
    use {super::*, std::convert::TryFrom};

    #[test]
    fn iter() {
        let e = Enumeration::try_from(&vec!["hello", "world", "💖"][..]).expect("enumeration?");
        let mut count = 0;
        let mut results = vec![];
        for result in e {
            let elem = result.expect("no error");
            count = count + 1;
            results.push(elem);
        }
        assert_eq!(count, 3, "results: {:?}", results);
        assert_eq!(
            results,
            vec!["hello", "world", "💖"],
            "results: {:?}",
            results
        );
    }

    #[test]
    fn error() {
        // A mutilated sparkle heart from https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html
        let destroyed_sparkle_heart = vec![0, 159, 164, 150];
        let invalid_utf8 = unsafe { str::from_utf8_unchecked(&destroyed_sparkle_heart) };
        let e = Enumeration::try_from(&vec!["hello", "world", "💖", invalid_utf8][..]);
        assert!(e.is_err(), "was: {:?}", e);
    }
}
