// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Cache the pipeline objects to disk for faster reloads.
//!
//! A pipeline cache is an opaque type that allow you to cache your graphics and compute
//! pipelines on the disk.
//!
//! You can create either an empty cache or a cache from some initial data. Whenever you create a
//! graphics or compute pipeline, you have the possibility to pass a reference to that cache.
//! The Vulkan implementation will then look in the cache for an existing entry, or add one if it
//! doesn't exist.
//!
//! Once that is done, you can extract the data from the cache and store it. See the documentation
//! of [`get_data`](struct.PipelineCache.html#method.get_data) for example of how to store the data
//! on the disk, and [`with_data`](struct.PipelineCache.html#method.with_data) for how to reload it.

use crate::check_errors;
use crate::device::Device;
use crate::OomError;
use crate::VulkanObject;
use std::mem::MaybeUninit;
use std::ptr;
use std::sync::Arc;

/// Opaque cache that contains pipeline objects.
///
/// See [the documentation of the module](index.html) for more info.
pub struct PipelineCache {
    device: Arc<Device>,
    cache: ash::vk::PipelineCache,
}

impl PipelineCache {
    /// Builds a new pipeline cache from existing data. The data must have been previously obtained
    /// with [`get_data`](#method.get_data).
    ///
    /// The data passed to this function will most likely be blindly trusted by the Vulkan
    /// implementation. Therefore you can easily crash your application or the system by passing
    /// wrong data. Hence why this function is unsafe.
    ///
    /// # Example
    ///
    /// This example loads a cache from a file, if it exists.
    /// See [`get_data`](#method.get_data) for how to store the data in a file.
    /// TODO: there's a header in the cached data that must be checked ; talk about this
    ///
    /// ```
    /// # use std::sync::Arc;
    /// # use vulkano::device::Device;
    /// use std::fs::File;
    /// use std::io::Read;
    /// use vulkano::pipeline::cache::PipelineCache;
    /// # let device: Arc<Device> = return;
    ///
    /// let data = {
    ///     let file = File::open("pipeline_cache.bin");
    ///     if let Ok(mut file) = file {
    ///         let mut data = Vec::new();
    ///         if let Ok(_) = file.read_to_end(&mut data) {
    ///             Some(data)
    ///         } else { None }
    ///     } else { None }
    /// };
    ///
    /// let cache = if let Some(data) = data {
    ///     // This is unsafe because there is no way to be sure that the file contains valid data.
    ///     unsafe { PipelineCache::with_data(device.clone(), &data).unwrap() }
    /// } else {
    ///     PipelineCache::empty(device.clone()).unwrap()
    /// };
    /// ```
    #[inline]
    pub unsafe fn with_data(
        device: Arc<Device>,
        initial_data: &[u8],
    ) -> Result<Arc<PipelineCache>, OomError> {
        PipelineCache::new_impl(device, Some(initial_data))
    }

    /// Builds a new empty pipeline cache.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::sync::Arc;
    /// # use vulkano::device::Device;
    /// use vulkano::pipeline::cache::PipelineCache;
    /// # let device: Arc<Device> = return;
    /// let cache = PipelineCache::empty(device.clone()).unwrap();
    /// ```
    #[inline]
    pub fn empty(device: Arc<Device>) -> Result<Arc<PipelineCache>, OomError> {
        unsafe { PipelineCache::new_impl(device, None) }
    }

    // Actual implementation of the constructor.
    unsafe fn new_impl(
        device: Arc<Device>,
        initial_data: Option<&[u8]>,
    ) -> Result<Arc<PipelineCache>, OomError> {
        let fns = device.fns();

        let cache = {
            let infos = ash::vk::PipelineCacheCreateInfo {
                flags: ash::vk::PipelineCacheCreateFlags::empty(),
                initial_data_size: initial_data.map(|d| d.len()).unwrap_or(0),
                p_initial_data: initial_data
                    .map(|d| d.as_ptr() as *const _)
                    .unwrap_or(ptr::null()),
                ..Default::default()
            };

            let mut output = MaybeUninit::uninit();
            check_errors(fns.v1_0.create_pipeline_cache(
                device.internal_object(),
                &infos,
                ptr::null(),
                output.as_mut_ptr(),
            ))?;
            output.assume_init()
        };

        Ok(Arc::new(PipelineCache {
            device: device.clone(),
            cache: cache,
        }))
    }

    /// Merges other pipeline caches into this one.
    ///
    /// It is `self` that is modified here. The pipeline caches passed as parameter are untouched.
    ///
    /// # Panic
    ///
    /// - Panics if `self` is included in the list of other pipelines.
    ///
    // FIXME: vkMergePipelineCaches is not thread safe for the destination cache
    // TODO: write example
    pub fn merge<'a, I>(&self, pipelines: I) -> Result<(), OomError>
    where
        I: IntoIterator<Item = &'a &'a Arc<PipelineCache>>,
    {
        unsafe {
            let fns = self.device.fns();

            let pipelines = pipelines
                .into_iter()
                .map(|pipeline| {
                    assert!(&***pipeline as *const _ != &*self as *const _);
                    pipeline.cache
                })
                .collect::<Vec<_>>();

            check_errors(fns.v1_0.merge_pipeline_caches(
                self.device.internal_object(),
                self.cache,
                pipelines.len() as u32,
                pipelines.as_ptr(),
            ))?;

            Ok(())
        }
    }

    /// Obtains the data from the cache.
    ///
    /// This data can be stored and then reloaded and passed to `PipelineCache::with_data`.
    ///
    /// # Example
    ///
    /// This example stores the data of a pipeline cache on the disk.
    /// See [`with_data`](#method.with_data) for how to reload it.
    ///
    /// ```
    /// use std::fs;
    /// use std::fs::File;
    /// use std::io::Write;
    /// # use std::sync::Arc;
    /// # use vulkano::pipeline::cache::PipelineCache;
    ///
    /// # let cache: Arc<PipelineCache> = return;
    /// // If an error happens (eg. no permission for the file) we simply skip storing the cache.
    /// if let Ok(data) = cache.get_data() {
    ///     if let Ok(mut file) = File::create("pipeline_cache.bin.tmp") {
    ///         if let Ok(_) = file.write_all(&data) {
    ///             let _ = fs::rename("pipeline_cache.bin.tmp", "pipeline_cache.bin");
    ///         } else {
    ///             let _ = fs::remove_file("pipeline_cache.bin.tmp");
    ///         }
    ///     }
    /// }
    /// ```
    pub fn get_data(&self) -> Result<Vec<u8>, OomError> {
        unsafe {
            let fns = self.device.fns();

            let mut num = 0;
            check_errors(fns.v1_0.get_pipeline_cache_data(
                self.device.internal_object(),
                self.cache,
                &mut num,
                ptr::null_mut(),
            ))?;

            let mut data: Vec<u8> = Vec::with_capacity(num as usize);
            check_errors(fns.v1_0.get_pipeline_cache_data(
                self.device.internal_object(),
                self.cache,
                &mut num,
                data.as_mut_ptr() as *mut _,
            ))?;
            data.set_len(num as usize);

            Ok(data)
        }
    }
}

unsafe impl VulkanObject for PipelineCache {
    type Object = ash::vk::PipelineCache;

    #[inline]
    fn internal_object(&self) -> ash::vk::PipelineCache {
        self.cache
    }
}

impl Drop for PipelineCache {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let fns = self.device.fns();
            fns.v1_0
                .destroy_pipeline_cache(self.device.internal_object(), self.cache, ptr::null());
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::pipeline::cache::PipelineCache;
    use crate::pipeline::shader::ShaderModule;
    use crate::pipeline::shader::SpecializationConstants;
    use crate::pipeline::ComputePipeline;
    use std::{ffi::CStr, sync::Arc};

    #[test]
    fn merge_self_forbidden() {
        let (device, queue) = gfx_dev_and_queue!();
        let pipeline = PipelineCache::empty(device).unwrap();
        assert_should_panic!({
            pipeline.merge(&[&pipeline]).unwrap();
        });
    }

    #[test]
    fn cache_returns_same_data() {
        let (device, queue) = gfx_dev_and_queue!();

        let cache = PipelineCache::empty(device.clone()).unwrap();

        let module = unsafe {
            /*
             * #version 450
             * void main() {
             * }
             */
            const MODULE: [u8; 192] = [
                3, 2, 35, 7, 0, 0, 1, 0, 10, 0, 8, 0, 6, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0,
                0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0,
                0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 5, 0, 5, 0, 0, 0, 4, 0, 0, 0,
                109, 97, 105, 110, 0, 0, 0, 0, 16, 0, 6, 0, 4, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 1,
                0, 0, 0, 1, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0,
                109, 97, 105, 110, 0, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2,
                0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0,
                5, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0,
            ];
            ShaderModule::new(device.clone(), &MODULE).unwrap()
        };

        let shader = unsafe {
            static NAME: [u8; 5] = [109, 97, 105, 110, 0]; // "main"
            module.compute_entry_point(
                CStr::from_ptr(NAME.as_ptr() as *const _),
                [],
                None,
                <()>::descriptors(),
            )
        };

        let pipeline = Arc::new(
            ComputePipeline::new(device.clone(), &shader, &(), Some(cache.clone())).unwrap(),
        );

        let cache_data = cache.get_data().unwrap();
        let second_data = cache.get_data().unwrap();

        assert_eq!(cache_data, second_data);
    }

    #[test]
    fn cache_returns_different_data() {
        let (device, queue) = gfx_dev_and_queue!();

        let cache = PipelineCache::empty(device.clone()).unwrap();

        let first_module = unsafe {
            /*
             * #version 450
             * void main() {
             * }
             */
            const MODULE: [u8; 192] = [
                3, 2, 35, 7, 0, 0, 1, 0, 10, 0, 8, 0, 6, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0,
                0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0,
                0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 5, 0, 5, 0, 0, 0, 4, 0, 0, 0,
                109, 97, 105, 110, 0, 0, 0, 0, 16, 0, 6, 0, 4, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 1,
                0, 0, 0, 1, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0,
                109, 97, 105, 110, 0, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2,
                0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0,
                5, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0,
            ];
            ShaderModule::new(device.clone(), &MODULE).unwrap()
        };

        let first_shader = unsafe {
            static NAME: [u8; 5] = [109, 97, 105, 110, 0]; // "main"
            first_module.compute_entry_point(
                CStr::from_ptr(NAME.as_ptr() as *const _),
                [],
                None,
                <()>::descriptors(),
            )
        };

        let second_module = unsafe {
            /*
             * #version 450
             *
             * void main() {
             *     uint idx = gl_GlobalInvocationID.x;
             * }
             */
            const SECOND_MODULE: [u8; 432] = [
                3, 2, 35, 7, 0, 0, 1, 0, 10, 0, 8, 0, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0,
                0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48,
                0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 6, 0, 5, 0, 0, 0, 4, 0, 0,
                0, 109, 97, 105, 110, 0, 0, 0, 0, 11, 0, 0, 0, 16, 0, 6, 0, 4, 0, 0, 0, 17, 0, 0,
                0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0,
                4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 3, 0, 8, 0, 0, 0, 105, 100,
                120, 0, 5, 0, 8, 0, 11, 0, 0, 0, 103, 108, 95, 71, 108, 111, 98, 97, 108, 73, 110,
                118, 111, 99, 97, 116, 105, 111, 110, 73, 68, 0, 0, 0, 71, 0, 4, 0, 11, 0, 0, 0,
                11, 0, 0, 0, 28, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0,
                0, 0, 21, 0, 4, 0, 6, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 7,
                0, 0, 0, 6, 0, 0, 0, 23, 0, 4, 0, 9, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0,
                10, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 11, 0, 0, 0, 1, 0,
                0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 13, 0, 0, 0,
                1, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
                0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 65,
                0, 5, 0, 13, 0, 0, 0, 14, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0,
                0, 15, 0, 0, 0, 14, 0, 0, 0, 62, 0, 3, 0, 8, 0, 0, 0, 15, 0, 0, 0, 253, 0, 1, 0,
                56, 0, 1, 0,
            ];
            ShaderModule::new(device.clone(), &SECOND_MODULE).unwrap()
        };

        let second_shader = unsafe {
            static NAME: [u8; 5] = [109, 97, 105, 110, 0]; // "main"
            second_module.compute_entry_point(
                CStr::from_ptr(NAME.as_ptr() as *const _),
                [],
                None,
                <()>::descriptors(),
            )
        };

        let pipeline = Arc::new(
            ComputePipeline::new(device.clone(), &first_shader, &(), Some(cache.clone())).unwrap(),
        );

        let cache_data = cache.get_data().unwrap();

        let second_pipeline = Arc::new(
            ComputePipeline::new(device.clone(), &second_shader, &(), Some(cache.clone())).unwrap(),
        );

        let second_data = cache.get_data().unwrap();

        if cache_data.is_empty() {
            assert_eq!(cache_data, second_data);
        } else {
            assert_ne!(cache_data, second_data);
        }
    }

    #[test]
    fn cache_data_does_not_change() {
        let (device, queue) = gfx_dev_and_queue!();

        let cache = PipelineCache::empty(device.clone()).unwrap();

        let module = unsafe {
            /*
             * #version 450
             * void main() {
             * }
             */
            const MODULE: [u8; 192] = [
                3, 2, 35, 7, 0, 0, 1, 0, 10, 0, 8, 0, 6, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0,
                0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0,
                0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 5, 0, 5, 0, 0, 0, 4, 0, 0, 0,
                109, 97, 105, 110, 0, 0, 0, 0, 16, 0, 6, 0, 4, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 1,
                0, 0, 0, 1, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0,
                109, 97, 105, 110, 0, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2,
                0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0,
                5, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0,
            ];
            ShaderModule::new(device.clone(), &MODULE).unwrap()
        };

        let shader = unsafe {
            static NAME: [u8; 5] = [109, 97, 105, 110, 0]; // "main"
            module.compute_entry_point(
                CStr::from_ptr(NAME.as_ptr() as *const _),
                [],
                None,
                <()>::descriptors(),
            )
        };

        let pipeline = Arc::new(
            ComputePipeline::new(device.clone(), &shader, &(), Some(cache.clone())).unwrap(),
        );

        let cache_data = cache.get_data().unwrap();

        let second_pipeline = Arc::new(
            ComputePipeline::new(device.clone(), &shader, &(), Some(cache.clone())).unwrap(),
        );

        let second_data = cache.get_data().unwrap();

        assert_eq!(cache_data, second_data);
    }
}
