use crate::build::CheckoutBuilder;
use crate::util::Binding;
use crate::{panic, raw, Oid, StashApplyProgress};
use libc::{c_char, c_int, c_void, size_t};
use std::ffi::CStr;
use std::mem;

/// Stash application progress notification function.
///
/// Return `true` to continue processing, or `false` to
/// abort the stash application.
pub type StashApplyProgressCb<'a> = dyn FnMut(StashApplyProgress) -> bool + 'a;

/// This is a callback function you can provide to iterate over all the
/// stashed states that will be invoked per entry.
pub type StashCb<'a> = dyn FnMut(usize, &str, &Oid) -> bool + 'a;

#[allow(unused)]
/// Stash application options structure
pub struct StashApplyOptions<'cb> {
    progress: Option<Box<StashApplyProgressCb<'cb>>>,
    checkout_options: Option<CheckoutBuilder<'cb>>,
    raw_opts: raw::git_stash_apply_options,
}

impl<'cb> Default for StashApplyOptions<'cb> {
    fn default() -> Self {
        Self::new()
    }
}

impl<'cb> StashApplyOptions<'cb> {
    /// Creates a default set of merge options.
    pub fn new() -> StashApplyOptions<'cb> {
        let mut opts = StashApplyOptions {
            progress: None,
            checkout_options: None,
            raw_opts: unsafe { mem::zeroed() },
        };
        assert_eq!(
            unsafe { raw::git_stash_apply_init_options(&mut opts.raw_opts, 1) },
            0
        );
        opts
    }

    /// Set stash application flag to GIT_STASH_APPLY_REINSTATE_INDEX
    pub fn reinstantiate_index(&mut self) -> &mut StashApplyOptions<'cb> {
        self.raw_opts.flags = raw::GIT_STASH_APPLY_REINSTATE_INDEX as u32;
        self
    }

    /// Options to use when writing files to the working directory
    pub fn checkout_options(&mut self, opts: CheckoutBuilder<'cb>) -> &mut StashApplyOptions<'cb> {
        self.checkout_options = Some(opts);
        self
    }

    /// Optional callback to notify the consumer of application progress.
    ///
    /// Return `true` to continue processing, or `false` to
    /// abort the stash application.
    pub fn progress_cb<C>(&mut self, callback: C) -> &mut StashApplyOptions<'cb>
    where
        C: FnMut(StashApplyProgress) -> bool + 'cb,
    {
        self.progress = Some(Box::new(callback) as Box<StashApplyProgressCb<'cb>>);
        self.raw_opts.progress_cb = Some(stash_apply_progress_cb);
        self.raw_opts.progress_payload = self as *mut _ as *mut _;
        self
    }

    /// Pointer to a raw git_stash_apply_options
    pub fn raw(&mut self) -> &raw::git_stash_apply_options {
        unsafe {
            if let Some(opts) = self.checkout_options.as_mut() {
                opts.configure(&mut self.raw_opts.checkout_options);
            }
        }
        &self.raw_opts
    }
}

#[allow(unused)]
pub struct StashCbData<'a> {
    pub callback: &'a mut StashCb<'a>,
}

#[allow(unused)]
pub extern "C" fn stash_cb(
    index: size_t,
    message: *const c_char,
    stash_id: *const raw::git_oid,
    payload: *mut c_void,
) -> c_int {
    panic::wrap(|| unsafe {
        let mut data = &mut *(payload as *mut StashCbData<'_>);
        let res = {
            let mut callback = &mut data.callback;
            callback(
                index,
                CStr::from_ptr(message).to_str().unwrap(),
                &Binding::from_raw(stash_id),
            )
        };

        if res {
            0
        } else {
            1
        }
    })
    .unwrap_or(1)
}

fn convert_progress(progress: raw::git_stash_apply_progress_t) -> StashApplyProgress {
    match progress {
        raw::GIT_STASH_APPLY_PROGRESS_NONE => StashApplyProgress::None,
        raw::GIT_STASH_APPLY_PROGRESS_LOADING_STASH => StashApplyProgress::LoadingStash,
        raw::GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX => StashApplyProgress::AnalyzeIndex,
        raw::GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED => StashApplyProgress::AnalyzeModified,
        raw::GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED => StashApplyProgress::AnalyzeUntracked,
        raw::GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED => StashApplyProgress::CheckoutUntracked,
        raw::GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED => StashApplyProgress::CheckoutModified,
        raw::GIT_STASH_APPLY_PROGRESS_DONE => StashApplyProgress::Done,

        _ => StashApplyProgress::None,
    }
}

#[allow(unused)]
extern "C" fn stash_apply_progress_cb(
    progress: raw::git_stash_apply_progress_t,
    payload: *mut c_void,
) -> c_int {
    panic::wrap(|| unsafe {
        let mut options = &mut *(payload as *mut StashApplyOptions<'_>);
        let res = {
            let mut callback = options.progress.as_mut().unwrap();
            callback(convert_progress(progress))
        };

        if res {
            0
        } else {
            -1
        }
    })
    .unwrap_or(-1)
}

#[cfg(test)]
mod tests {
    use crate::stash::StashApplyOptions;
    use crate::test::repo_init;
    use crate::{Repository, StashFlags, Status};
    use std::fs;
    use std::io::Write;
    use std::path::Path;

    fn make_stash<C>(next: C)
    where
        C: FnOnce(&mut Repository),
    {
        let (_td, mut repo) = repo_init();
        let signature = repo.signature().unwrap();

        let p = Path::new(repo.workdir().unwrap()).join("file_b.txt");
        println!("using path {:?}", p);
        fs::File::create(&p)
            .unwrap()
            .write("data".as_bytes())
            .unwrap();

        let rel_p = Path::new("file_b.txt");
        assert!(repo.status_file(&rel_p).unwrap() == Status::WT_NEW);

        repo.stash_save(&signature, "msg1", Some(StashFlags::INCLUDE_UNTRACKED))
            .unwrap();

        assert!(repo.status_file(&rel_p).is_err());

        let mut count = 0;
        repo.stash_foreach(|index, name, _oid| {
            count += 1;
            assert!(index == 0);
            assert!(name == "On main: msg1");
            true
        })
        .unwrap();

        assert!(count == 1);
        next(&mut repo);
    }

    fn count_stash(repo: &mut Repository) -> usize {
        let mut count = 0;
        repo.stash_foreach(|_, _, _| {
            count += 1;
            true
        })
        .unwrap();
        count
    }

    #[test]
    fn smoke_stash_save_drop() {
        make_stash(|repo| {
            repo.stash_drop(0).unwrap();
            assert!(count_stash(repo) == 0)
        })
    }

    #[test]
    fn smoke_stash_save_pop() {
        make_stash(|repo| {
            repo.stash_pop(0, None).unwrap();
            assert!(count_stash(repo) == 0)
        })
    }

    #[test]
    fn smoke_stash_save_apply() {
        make_stash(|repo| {
            let mut options = StashApplyOptions::new();
            options.progress_cb(|progress| {
                println!("{:?}", progress);
                true
            });

            repo.stash_apply(0, Some(&mut options)).unwrap();
            assert!(count_stash(repo) == 1)
        })
    }

    #[test]
    fn test_stash_save2_msg_none() {
        let (_td, mut repo) = repo_init();
        let signature = repo.signature().unwrap();

        let p = Path::new(repo.workdir().unwrap()).join("file_b.txt");

        fs::File::create(&p)
            .unwrap()
            .write("data".as_bytes())
            .unwrap();

        repo.stash_save2(&signature, None, Some(StashFlags::INCLUDE_UNTRACKED))
            .unwrap();

        let mut stash_name = String::new();
        repo.stash_foreach(|index, name, _oid| {
            assert_eq!(index, 0);
            stash_name = name.to_string();
            true
        })
        .unwrap();

        assert!(stash_name.starts_with("WIP on main:"));
    }
}
