use libc;
use raw::git_strarray;
use std::marker;
use std::mem;
use std::ops::Range;
use std::ptr;
use std::slice;
use std::str;
use std::{ffi::CString, os::raw::c_char};

use crate::string_array::StringArray;
use crate::util::Binding;
use crate::{raw, Buf, Direction, Error, FetchPrune, Oid, ProxyOptions, Refspec};
use crate::{AutotagOption, Progress, RemoteCallbacks, Repository};

/// A structure representing a [remote][1] of a git repository.
///
/// [1]: http://git-scm.com/book/en/Git-Basics-Working-with-Remotes
///
/// The lifetime is the lifetime of the repository that it is attached to. The
/// remote is used to manage fetches and pushes as well as refspecs.
pub struct Remote<'repo> {
    raw: *mut raw::git_remote,
    _marker: marker::PhantomData<&'repo Repository>,
}

/// An iterator over the refspecs that a remote contains.
pub struct Refspecs<'remote> {
    range: Range<usize>,
    remote: &'remote Remote<'remote>,
}

/// Description of a reference advertised by a remote server, given out on calls
/// to `list`.
pub struct RemoteHead<'remote> {
    raw: *const raw::git_remote_head,
    _marker: marker::PhantomData<&'remote str>,
}

/// Options which can be specified to various fetch operations.
pub struct FetchOptions<'cb> {
    callbacks: Option<RemoteCallbacks<'cb>>,
    proxy: Option<ProxyOptions<'cb>>,
    prune: FetchPrune,
    update_fetchhead: bool,
    download_tags: AutotagOption,
    custom_headers: Vec<CString>,
    custom_headers_ptrs: Vec<*const c_char>,
}

/// Options to control the behavior of a git push.
pub struct PushOptions<'cb> {
    callbacks: Option<RemoteCallbacks<'cb>>,
    proxy: Option<ProxyOptions<'cb>>,
    pb_parallelism: u32,
    custom_headers: Vec<CString>,
    custom_headers_ptrs: Vec<*const c_char>,
}

/// Holds callbacks for a connection to a `Remote`. Disconnects when dropped
pub struct RemoteConnection<'repo, 'connection, 'cb> {
    _callbacks: Box<RemoteCallbacks<'cb>>,
    _proxy: ProxyOptions<'cb>,
    remote: &'connection mut Remote<'repo>,
}

pub fn remote_into_raw(remote: Remote<'_>) -> *mut raw::git_remote {
    let ret = remote.raw;
    mem::forget(remote);
    ret
}

impl<'repo> Remote<'repo> {
    /// Ensure the remote name is well-formed.
    pub fn is_valid_name(remote_name: &str) -> bool {
        crate::init();
        let remote_name = CString::new(remote_name).unwrap();
        unsafe { raw::git_remote_is_valid_name(remote_name.as_ptr()) == 1 }
    }

    /// Create a detached remote
    ///
    /// Create a remote with the given url in-memory. You can use this
    /// when you have a URL instead of a remote's name.
    /// Contrasted with an anonymous remote, a detached remote will not
    /// consider any repo configuration values.
    pub fn create_detached(url: &str) -> Result<Remote<'_>, Error> {
        crate::init();
        let mut ret = ptr::null_mut();
        let url = CString::new(url)?;
        unsafe {
            try_call!(raw::git_remote_create_detached(&mut ret, url));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Get the remote's name.
    ///
    /// Returns `None` if this remote has not yet been named or if the name is
    /// not valid utf-8
    pub fn name(&self) -> Option<&str> {
        self.name_bytes().and_then(|s| str::from_utf8(s).ok())
    }

    /// Get the remote's name, in bytes.
    ///
    /// Returns `None` if this remote has not yet been named
    pub fn name_bytes(&self) -> Option<&[u8]> {
        unsafe { crate::opt_bytes(self, raw::git_remote_name(&*self.raw)) }
    }

    /// Get the remote's url.
    ///
    /// Returns `None` if the url is not valid utf-8
    pub fn url(&self) -> Option<&str> {
        str::from_utf8(self.url_bytes()).ok()
    }

    /// Get the remote's url as a byte array.
    pub fn url_bytes(&self) -> &[u8] {
        unsafe { crate::opt_bytes(self, raw::git_remote_url(&*self.raw)).unwrap() }
    }

    /// Get the remote's pushurl.
    ///
    /// Returns `None` if the pushurl is not valid utf-8
    pub fn pushurl(&self) -> Option<&str> {
        self.pushurl_bytes().and_then(|s| str::from_utf8(s).ok())
    }

    /// Get the remote's pushurl as a byte array.
    pub fn pushurl_bytes(&self) -> Option<&[u8]> {
        unsafe { crate::opt_bytes(self, raw::git_remote_pushurl(&*self.raw)) }
    }

    /// Get the remote's default branch.
    ///
    /// The remote (or more exactly its transport) must have connected to the
    /// remote repository. This default branch is available as soon as the
    /// connection to the remote is initiated and it remains available after
    /// disconnecting.
    pub fn default_branch(&self) -> Result<Buf, Error> {
        unsafe {
            let buf = Buf::new();
            try_call!(raw::git_remote_default_branch(buf.raw(), self.raw));
            Ok(buf)
        }
    }

    /// Open a connection to a remote.
    pub fn connect(&mut self, dir: Direction) -> Result<(), Error> {
        // TODO: can callbacks be exposed safely?
        unsafe {
            try_call!(raw::git_remote_connect(
                self.raw,
                dir,
                ptr::null(),
                ptr::null(),
                ptr::null()
            ));
        }
        Ok(())
    }

    /// Open a connection to a remote with callbacks and proxy settings
    ///
    /// Returns a `RemoteConnection` that will disconnect once dropped
    pub fn connect_auth<'connection, 'cb>(
        &'connection mut self,
        dir: Direction,
        cb: Option<RemoteCallbacks<'cb>>,
        proxy_options: Option<ProxyOptions<'cb>>,
    ) -> Result<RemoteConnection<'repo, 'connection, 'cb>, Error> {
        let cb = Box::new(cb.unwrap_or_else(RemoteCallbacks::new));
        let proxy_options = proxy_options.unwrap_or_else(ProxyOptions::new);
        unsafe {
            try_call!(raw::git_remote_connect(
                self.raw,
                dir,
                &cb.raw(),
                &proxy_options.raw(),
                ptr::null()
            ));
        }

        Ok(RemoteConnection {
            _callbacks: cb,
            _proxy: proxy_options,
            remote: self,
        })
    }

    /// Check whether the remote is connected
    pub fn connected(&mut self) -> bool {
        unsafe { raw::git_remote_connected(self.raw) == 1 }
    }

    /// Disconnect from the remote
    pub fn disconnect(&mut self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_remote_disconnect(self.raw));
        }
        Ok(())
    }

    /// Download and index the packfile
    ///
    /// Connect to the remote if it hasn't been done yet, negotiate with the
    /// remote git which objects are missing, download and index the packfile.
    ///
    /// The .idx file will be created and both it and the packfile with be
    /// renamed to their final name.
    ///
    /// The `specs` argument is a list of refspecs to use for this negotiation
    /// and download. Use an empty array to use the base refspecs.
    pub fn download<Str: AsRef<str> + crate::IntoCString + Clone>(
        &mut self,
        specs: &[Str],
        opts: Option<&mut FetchOptions<'_>>,
    ) -> Result<(), Error> {
        let (_a, _b, arr) = crate::util::iter2cstrs(specs.iter())?;
        let raw = opts.map(|o| o.raw());
        unsafe {
            try_call!(raw::git_remote_download(self.raw, &arr, raw.as_ref()));
        }
        Ok(())
    }

    /// Cancel the operation
    ///
    /// At certain points in its operation, the network code checks whether the
    /// operation has been cancelled and if so stops the operation.
    pub fn stop(&mut self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_remote_stop(self.raw));
        }
        Ok(())
    }

    /// Get the number of refspecs for a remote
    pub fn refspecs(&self) -> Refspecs<'_> {
        let cnt = unsafe { raw::git_remote_refspec_count(&*self.raw) as usize };
        Refspecs {
            range: 0..cnt,
            remote: self,
        }
    }

    /// Get the `nth` refspec from this remote.
    ///
    /// The `refspecs` iterator can be used to iterate over all refspecs.
    pub fn get_refspec(&self, i: usize) -> Option<Refspec<'repo>> {
        unsafe {
            let ptr = raw::git_remote_get_refspec(&*self.raw, i as libc::size_t);
            Binding::from_raw_opt(ptr)
        }
    }

    /// Download new data and update tips
    ///
    /// Convenience function to connect to a remote, download the data,
    /// disconnect and update the remote-tracking branches.
    ///
    /// # Examples
    ///
    /// Example of functionality similar to `git fetch origin/main`:
    ///
    /// ```no_run
    /// fn fetch_origin_main(repo: git2::Repository) -> Result<(), git2::Error> {
    ///     repo.find_remote("origin")?.fetch(&["main"], None, None)
    /// }
    ///
    /// let repo = git2::Repository::discover("rust").unwrap();
    /// fetch_origin_main(repo).unwrap();
    /// ```
    pub fn fetch<Str: AsRef<str> + crate::IntoCString + Clone>(
        &mut self,
        refspecs: &[Str],
        opts: Option<&mut FetchOptions<'_>>,
        reflog_msg: Option<&str>,
    ) -> Result<(), Error> {
        let (_a, _b, arr) = crate::util::iter2cstrs(refspecs.iter())?;
        let msg = crate::opt_cstr(reflog_msg)?;
        let raw = opts.map(|o| o.raw());
        unsafe {
            try_call!(raw::git_remote_fetch(self.raw, &arr, raw.as_ref(), msg));
        }
        Ok(())
    }

    /// Update the tips to the new state
    pub fn update_tips(
        &mut self,
        callbacks: Option<&mut RemoteCallbacks<'_>>,
        update_fetchhead: bool,
        download_tags: AutotagOption,
        msg: Option<&str>,
    ) -> Result<(), Error> {
        let msg = crate::opt_cstr(msg)?;
        let cbs = callbacks.map(|cb| cb.raw());
        unsafe {
            try_call!(raw::git_remote_update_tips(
                self.raw,
                cbs.as_ref(),
                update_fetchhead,
                download_tags,
                msg
            ));
        }
        Ok(())
    }

    /// Perform a push
    ///
    /// Perform all the steps for a push. If no refspecs are passed then the
    /// configured refspecs will be used.
    ///
    /// Note that you'll likely want to use `RemoteCallbacks` and set
    /// `push_update_reference` to test whether all the references were pushed
    /// successfully.
    pub fn push<Str: AsRef<str> + crate::IntoCString + Clone>(
        &mut self,
        refspecs: &[Str],
        opts: Option<&mut PushOptions<'_>>,
    ) -> Result<(), Error> {
        let (_a, _b, arr) = crate::util::iter2cstrs(refspecs.iter())?;
        let raw = opts.map(|o| o.raw());
        unsafe {
            try_call!(raw::git_remote_push(self.raw, &arr, raw.as_ref()));
        }
        Ok(())
    }

    /// Get the statistics structure that is filled in by the fetch operation.
    pub fn stats(&self) -> Progress<'_> {
        unsafe { Binding::from_raw(raw::git_remote_stats(self.raw)) }
    }

    /// Get the remote repository's reference advertisement list.
    ///
    /// Get the list of references with which the server responds to a new
    /// connection.
    ///
    /// The remote (or more exactly its transport) must have connected to the
    /// remote repository. This list is available as soon as the connection to
    /// the remote is initiated and it remains available after disconnecting.
    pub fn list(&self) -> Result<&[RemoteHead<'_>], Error> {
        let mut size = 0;
        let mut base = ptr::null_mut();
        unsafe {
            try_call!(raw::git_remote_ls(&mut base, &mut size, self.raw));
            assert_eq!(
                mem::size_of::<RemoteHead<'_>>(),
                mem::size_of::<*const raw::git_remote_head>()
            );
            let slice = slice::from_raw_parts(base as *const _, size as usize);
            Ok(mem::transmute::<
                &[*const raw::git_remote_head],
                &[RemoteHead<'_>],
            >(slice))
        }
    }

    /// Prune tracking refs that are no longer present on remote
    pub fn prune(&mut self, callbacks: Option<RemoteCallbacks<'_>>) -> Result<(), Error> {
        let cbs = Box::new(callbacks.unwrap_or_else(RemoteCallbacks::new));
        unsafe {
            try_call!(raw::git_remote_prune(self.raw, &cbs.raw()));
        }
        Ok(())
    }

    /// Get the remote's list of fetch refspecs
    pub fn fetch_refspecs(&self) -> Result<StringArray, Error> {
        unsafe {
            let mut raw: raw::git_strarray = mem::zeroed();
            try_call!(raw::git_remote_get_fetch_refspecs(&mut raw, self.raw));
            Ok(StringArray::from_raw(raw))
        }
    }

    /// Get the remote's list of push refspecs
    pub fn push_refspecs(&self) -> Result<StringArray, Error> {
        unsafe {
            let mut raw: raw::git_strarray = mem::zeroed();
            try_call!(raw::git_remote_get_push_refspecs(&mut raw, self.raw));
            Ok(StringArray::from_raw(raw))
        }
    }
}

impl<'repo> Clone for Remote<'repo> {
    fn clone(&self) -> Remote<'repo> {
        let mut ret = ptr::null_mut();
        let rc = unsafe { call!(raw::git_remote_dup(&mut ret, self.raw)) };
        assert_eq!(rc, 0);
        Remote {
            raw: ret,
            _marker: marker::PhantomData,
        }
    }
}

impl<'repo> Binding for Remote<'repo> {
    type Raw = *mut raw::git_remote;

    unsafe fn from_raw(raw: *mut raw::git_remote) -> Remote<'repo> {
        Remote {
            raw,
            _marker: marker::PhantomData,
        }
    }
    fn raw(&self) -> *mut raw::git_remote {
        self.raw
    }
}

impl<'repo> Drop for Remote<'repo> {
    fn drop(&mut self) {
        unsafe { raw::git_remote_free(self.raw) }
    }
}

impl<'repo> Iterator for Refspecs<'repo> {
    type Item = Refspec<'repo>;
    fn next(&mut self) -> Option<Refspec<'repo>> {
        self.range.next().and_then(|i| self.remote.get_refspec(i))
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.range.size_hint()
    }
}
impl<'repo> DoubleEndedIterator for Refspecs<'repo> {
    fn next_back(&mut self) -> Option<Refspec<'repo>> {
        self.range
            .next_back()
            .and_then(|i| self.remote.get_refspec(i))
    }
}
impl<'repo> ExactSizeIterator for Refspecs<'repo> {}

#[allow(missing_docs)] // not documented in libgit2 :(
impl<'remote> RemoteHead<'remote> {
    /// Flag if this is available locally.
    pub fn is_local(&self) -> bool {
        unsafe { (*self.raw).local != 0 }
    }

    pub fn oid(&self) -> Oid {
        unsafe { Binding::from_raw(&(*self.raw).oid as *const _) }
    }
    pub fn loid(&self) -> Oid {
        unsafe { Binding::from_raw(&(*self.raw).loid as *const _) }
    }

    pub fn name(&self) -> &str {
        let b = unsafe { crate::opt_bytes(self, (*self.raw).name).unwrap() };
        str::from_utf8(b).unwrap()
    }

    pub fn symref_target(&self) -> Option<&str> {
        let b = unsafe { crate::opt_bytes(self, (*self.raw).symref_target) };
        b.map(|b| str::from_utf8(b).unwrap())
    }
}

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

impl<'cb> FetchOptions<'cb> {
    /// Creates a new blank set of fetch options
    pub fn new() -> FetchOptions<'cb> {
        FetchOptions {
            callbacks: None,
            proxy: None,
            prune: FetchPrune::Unspecified,
            update_fetchhead: true,
            download_tags: AutotagOption::Unspecified,
            custom_headers: Vec::new(),
            custom_headers_ptrs: Vec::new(),
        }
    }

    /// Set the callbacks to use for the fetch operation.
    pub fn remote_callbacks(&mut self, cbs: RemoteCallbacks<'cb>) -> &mut Self {
        self.callbacks = Some(cbs);
        self
    }

    /// Set the proxy options to use for the fetch operation.
    pub fn proxy_options(&mut self, opts: ProxyOptions<'cb>) -> &mut Self {
        self.proxy = Some(opts);
        self
    }

    /// Set whether to perform a prune after the fetch.
    pub fn prune(&mut self, prune: FetchPrune) -> &mut Self {
        self.prune = prune;
        self
    }

    /// Set whether to write the results to FETCH_HEAD.
    ///
    /// Defaults to `true`.
    pub fn update_fetchhead(&mut self, update: bool) -> &mut Self {
        self.update_fetchhead = update;
        self
    }

    /// Set how to behave regarding tags on the remote, such as auto-downloading
    /// tags for objects we're downloading or downloading all of them.
    ///
    /// The default is to auto-follow tags.
    pub fn download_tags(&mut self, opt: AutotagOption) -> &mut Self {
        self.download_tags = opt;
        self
    }

    /// Set extra headers for this fetch operation.
    pub fn custom_headers(&mut self, custom_headers: &[&str]) -> &mut Self {
        self.custom_headers = custom_headers
            .iter()
            .map(|&s| CString::new(s).unwrap())
            .collect();
        self.custom_headers_ptrs = self.custom_headers.iter().map(|s| s.as_ptr()).collect();
        self
    }
}

impl<'cb> Binding for FetchOptions<'cb> {
    type Raw = raw::git_fetch_options;

    unsafe fn from_raw(_raw: raw::git_fetch_options) -> FetchOptions<'cb> {
        panic!("unimplemented");
    }
    fn raw(&self) -> raw::git_fetch_options {
        raw::git_fetch_options {
            version: 1,
            callbacks: self
                .callbacks
                .as_ref()
                .map(|m| m.raw())
                .unwrap_or_else(|| RemoteCallbacks::new().raw()),
            proxy_opts: self
                .proxy
                .as_ref()
                .map(|m| m.raw())
                .unwrap_or_else(|| ProxyOptions::new().raw()),
            prune: crate::call::convert(&self.prune),
            update_fetchhead: crate::call::convert(&self.update_fetchhead),
            download_tags: crate::call::convert(&self.download_tags),
            custom_headers: git_strarray {
                count: self.custom_headers_ptrs.len(),
                strings: self.custom_headers_ptrs.as_ptr() as *mut _,
            },
        }
    }
}

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

impl<'cb> PushOptions<'cb> {
    /// Creates a new blank set of push options
    pub fn new() -> PushOptions<'cb> {
        PushOptions {
            callbacks: None,
            proxy: None,
            pb_parallelism: 1,
            custom_headers: Vec::new(),
            custom_headers_ptrs: Vec::new(),
        }
    }

    /// Set the callbacks to use for the fetch operation.
    pub fn remote_callbacks(&mut self, cbs: RemoteCallbacks<'cb>) -> &mut Self {
        self.callbacks = Some(cbs);
        self
    }

    /// Set the proxy options to use for the fetch operation.
    pub fn proxy_options(&mut self, opts: ProxyOptions<'cb>) -> &mut Self {
        self.proxy = Some(opts);
        self
    }

    /// If the transport being used to push to the remote requires the creation
    /// of a pack file, this controls the number of worker threads used by the
    /// packbuilder when creating that pack file to be sent to the remote.
    ///
    /// if set to 0 the packbuilder will auto-detect the number of threads to
    /// create, and the default value is 1.
    pub fn packbuilder_parallelism(&mut self, parallel: u32) -> &mut Self {
        self.pb_parallelism = parallel;
        self
    }

    /// Set extra headers for this push operation.
    pub fn custom_headers(&mut self, custom_headers: &[&str]) -> &mut Self {
        self.custom_headers = custom_headers
            .iter()
            .map(|&s| CString::new(s).unwrap())
            .collect();
        self.custom_headers_ptrs = self.custom_headers.iter().map(|s| s.as_ptr()).collect();
        self
    }
}

impl<'cb> Binding for PushOptions<'cb> {
    type Raw = raw::git_push_options;

    unsafe fn from_raw(_raw: raw::git_push_options) -> PushOptions<'cb> {
        panic!("unimplemented");
    }
    fn raw(&self) -> raw::git_push_options {
        raw::git_push_options {
            version: 1,
            callbacks: self
                .callbacks
                .as_ref()
                .map(|m| m.raw())
                .unwrap_or_else(|| RemoteCallbacks::new().raw()),
            proxy_opts: self
                .proxy
                .as_ref()
                .map(|m| m.raw())
                .unwrap_or_else(|| ProxyOptions::new().raw()),
            pb_parallelism: self.pb_parallelism as libc::c_uint,
            custom_headers: git_strarray {
                count: self.custom_headers_ptrs.len(),
                strings: self.custom_headers_ptrs.as_ptr() as *mut _,
            },
        }
    }
}

impl<'repo, 'connection, 'cb> RemoteConnection<'repo, 'connection, 'cb> {
    /// Check whether the remote is (still) connected
    pub fn connected(&mut self) -> bool {
        self.remote.connected()
    }

    /// Get the remote repository's reference advertisement list.
    ///
    /// This list is available as soon as the connection to
    /// the remote is initiated and it remains available after disconnecting.
    pub fn list(&self) -> Result<&[RemoteHead<'_>], Error> {
        self.remote.list()
    }

    /// Get the remote's default branch.
    ///
    /// This default branch is available as soon as the connection to the remote
    /// is initiated and it remains available after disconnecting.
    pub fn default_branch(&self) -> Result<Buf, Error> {
        self.remote.default_branch()
    }

    /// access remote bound to this connection
    pub fn remote(&mut self) -> &mut Remote<'repo> {
        self.remote
    }
}

impl<'repo, 'connection, 'cb> Drop for RemoteConnection<'repo, 'connection, 'cb> {
    fn drop(&mut self) {
        drop(self.remote.disconnect());
    }
}

#[cfg(test)]
mod tests {
    use crate::{AutotagOption, PushOptions};
    use crate::{Direction, FetchOptions, Remote, RemoteCallbacks, Repository};
    use std::cell::Cell;
    use tempfile::TempDir;

    #[test]
    fn smoke() {
        let (td, repo) = crate::test::repo_init();
        t!(repo.remote("origin", "/path/to/nowhere"));
        drop(repo);

        let repo = t!(Repository::init(td.path()));
        let mut origin = t!(repo.find_remote("origin"));
        assert_eq!(origin.name(), Some("origin"));
        assert_eq!(origin.url(), Some("/path/to/nowhere"));
        assert_eq!(origin.pushurl(), None);

        t!(repo.remote_set_url("origin", "/path/to/elsewhere"));
        t!(repo.remote_set_pushurl("origin", Some("/path/to/elsewhere")));

        let stats = origin.stats();
        assert_eq!(stats.total_objects(), 0);

        t!(origin.stop());
    }

    #[test]
    fn create_remote() {
        let td = TempDir::new().unwrap();
        let remote = td.path().join("remote");
        Repository::init_bare(&remote).unwrap();

        let (_td, repo) = crate::test::repo_init();
        let url = if cfg!(unix) {
            format!("file://{}", remote.display())
        } else {
            format!(
                "file:///{}",
                remote.display().to_string().replace("\\", "/")
            )
        };

        let mut origin = repo.remote("origin", &url).unwrap();
        assert_eq!(origin.name(), Some("origin"));
        assert_eq!(origin.url(), Some(&url[..]));
        assert_eq!(origin.pushurl(), None);

        {
            let mut specs = origin.refspecs();
            let spec = specs.next().unwrap();
            assert!(specs.next().is_none());
            assert_eq!(spec.str(), Some("+refs/heads/*:refs/remotes/origin/*"));
            assert_eq!(spec.dst(), Some("refs/remotes/origin/*"));
            assert_eq!(spec.src(), Some("refs/heads/*"));
            assert!(spec.is_force());
        }
        assert!(origin.refspecs().next_back().is_some());
        {
            let remotes = repo.remotes().unwrap();
            assert_eq!(remotes.len(), 1);
            assert_eq!(remotes.get(0), Some("origin"));
            assert_eq!(remotes.iter().count(), 1);
            assert_eq!(remotes.iter().next().unwrap(), Some("origin"));
        }

        origin.connect(Direction::Push).unwrap();
        assert!(origin.connected());
        origin.disconnect().unwrap();

        origin.connect(Direction::Fetch).unwrap();
        assert!(origin.connected());
        origin.download(&[] as &[&str], None).unwrap();
        origin.disconnect().unwrap();

        {
            let mut connection = origin.connect_auth(Direction::Push, None, None).unwrap();
            assert!(connection.connected());
        }
        assert!(!origin.connected());

        {
            let mut connection = origin.connect_auth(Direction::Fetch, None, None).unwrap();
            assert!(connection.connected());
        }
        assert!(!origin.connected());

        origin.fetch(&[] as &[&str], None, None).unwrap();
        origin.fetch(&[] as &[&str], None, Some("foo")).unwrap();
        origin
            .update_tips(None, true, AutotagOption::Unspecified, None)
            .unwrap();
        origin
            .update_tips(None, true, AutotagOption::All, Some("foo"))
            .unwrap();

        t!(repo.remote_add_fetch("origin", "foo"));
        t!(repo.remote_add_fetch("origin", "bar"));
    }

    #[test]
    fn rename_remote() {
        let (_td, repo) = crate::test::repo_init();
        repo.remote("origin", "foo").unwrap();
        drop(repo.remote_rename("origin", "foo"));
        drop(repo.remote_delete("foo"));
    }

    #[test]
    fn create_remote_anonymous() {
        let td = TempDir::new().unwrap();
        let repo = Repository::init(td.path()).unwrap();

        let origin = repo.remote_anonymous("/path/to/nowhere").unwrap();
        assert_eq!(origin.name(), None);
        drop(origin.clone());
    }

    #[test]
    fn is_valid() {
        assert!(Remote::is_valid_name("foobar"));
        assert!(!Remote::is_valid_name("\x01"));
    }

    #[test]
    fn transfer_cb() {
        let (td, _repo) = crate::test::repo_init();
        let td2 = TempDir::new().unwrap();
        let url = crate::test::path2url(&td.path());

        let repo = Repository::init(td2.path()).unwrap();
        let progress_hit = Cell::new(false);
        {
            let mut callbacks = RemoteCallbacks::new();
            let mut origin = repo.remote("origin", &url).unwrap();

            callbacks.transfer_progress(|_progress| {
                progress_hit.set(true);
                true
            });
            origin
                .fetch(
                    &[] as &[&str],
                    Some(FetchOptions::new().remote_callbacks(callbacks)),
                    None,
                )
                .unwrap();

            let list = t!(origin.list());
            assert_eq!(list.len(), 2);
            assert_eq!(list[0].name(), "HEAD");
            assert!(!list[0].is_local());
            assert_eq!(list[1].name(), "refs/heads/main");
            assert!(!list[1].is_local());
        }
        assert!(progress_hit.get());
    }

    /// This test is meant to assure that the callbacks provided to connect will not cause
    /// segfaults
    #[test]
    fn connect_list() {
        let (td, _repo) = crate::test::repo_init();
        let td2 = TempDir::new().unwrap();
        let url = crate::test::path2url(&td.path());

        let repo = Repository::init(td2.path()).unwrap();
        let mut callbacks = RemoteCallbacks::new();
        callbacks.sideband_progress(|_progress| {
            // no-op
            true
        });

        let mut origin = repo.remote("origin", &url).unwrap();

        {
            let mut connection = origin
                .connect_auth(Direction::Fetch, Some(callbacks), None)
                .unwrap();
            assert!(connection.connected());

            let list = t!(connection.list());
            assert_eq!(list.len(), 2);
            assert_eq!(list[0].name(), "HEAD");
            assert!(!list[0].is_local());
            assert_eq!(list[1].name(), "refs/heads/main");
            assert!(!list[1].is_local());
        }
        assert!(!origin.connected());
    }

    #[test]
    fn push() {
        let (_td, repo) = crate::test::repo_init();
        let td2 = TempDir::new().unwrap();
        let td3 = TempDir::new().unwrap();
        let url = crate::test::path2url(&td2.path());

        let mut opts = crate::RepositoryInitOptions::new();
        opts.bare(true);
        opts.initial_head("main");
        Repository::init_opts(td2.path(), &opts).unwrap();
        // git push
        let mut remote = repo.remote("origin", &url).unwrap();
        let mut updated = false;
        {
            let mut callbacks = RemoteCallbacks::new();
            callbacks.push_update_reference(|refname, status| {
                updated = true;
                assert_eq!(refname, "refs/heads/main");
                assert_eq!(status, None);
                Ok(())
            });
            let mut options = PushOptions::new();
            options.remote_callbacks(callbacks);
            remote
                .push(&["refs/heads/main"], Some(&mut options))
                .unwrap();
        }
        assert!(updated);

        let repo = Repository::clone(&url, td3.path()).unwrap();
        let commit = repo.head().unwrap().target().unwrap();
        let commit = repo.find_commit(commit).unwrap();
        assert_eq!(commit.message(), Some("initial"));
    }

    #[test]
    fn prune() {
        let (td, remote_repo) = crate::test::repo_init();
        let oid = remote_repo.head().unwrap().target().unwrap();
        let commit = remote_repo.find_commit(oid).unwrap();
        remote_repo.branch("stale", &commit, true).unwrap();

        let td2 = TempDir::new().unwrap();
        let url = crate::test::path2url(&td.path());
        let repo = Repository::clone(&url, &td2).unwrap();

        fn assert_branch_count(repo: &Repository, count: usize) {
            assert_eq!(
                repo.branches(Some(crate::BranchType::Remote))
                    .unwrap()
                    .filter(|b| b.as_ref().unwrap().0.name().unwrap() == Some("origin/stale"))
                    .count(),
                count,
            );
        }

        assert_branch_count(&repo, 1);

        // delete `stale` branch on remote repo
        let mut stale_branch = remote_repo
            .find_branch("stale", crate::BranchType::Local)
            .unwrap();
        stale_branch.delete().unwrap();

        // prune
        let mut remote = repo.find_remote("origin").unwrap();
        remote.connect(Direction::Push).unwrap();
        let mut callbacks = RemoteCallbacks::new();
        callbacks.update_tips(|refname, _a, b| {
            assert_eq!(refname, "refs/remotes/origin/stale");
            assert!(b.is_zero());
            true
        });
        remote.prune(Some(callbacks)).unwrap();
        assert_branch_count(&repo, 0);
    }
}
