#![cfg(feature = "git")]

mod utils;
use tame_index::{
    index::RemoteGitIndex, GitIndex, IndexKrate, IndexLocation, IndexPath, IndexUrl, Path,
};

fn remote_index(
    path: impl AsRef<tame_index::Path>,
    url: impl AsRef<tame_index::Path>,
) -> RemoteGitIndex {
    RemoteGitIndex::new(
        GitIndex::new(IndexLocation {
            url: IndexUrl::NonCratesIo(url.as_ref().as_str().into()),
            root: IndexPath::Exact(path.as_ref().join("sub/dir")),
        })
        .unwrap(),
        &utils::unlocked(),
    )
    .unwrap()
}

enum UpdateEntry {
    Blob(gix::ObjectId),
    Tree(UpdateTree),
}

type UpdateTree = std::collections::BTreeMap<String, UpdateEntry>;

struct TreeUpdateBuilder {
    update_tree: UpdateTree,
}

impl TreeUpdateBuilder {
    fn new() -> Self {
        Self {
            update_tree: UpdateTree::new(),
        }
    }

    fn upsert_blob(&mut self, path: &Path, oid: gix::ObjectId) {
        let ancestors = path.parent().unwrap();
        let file_name = path.file_name().unwrap();

        let mut ct = &mut self.update_tree;

        for comp in ancestors.components().filter_map(|com| {
            if let camino::Utf8Component::Normal(n) = com {
                Some(n)
            } else {
                None
            }
        }) {
            let entry = ct
                .entry(comp.to_owned())
                .or_insert_with(|| UpdateEntry::Tree(UpdateTree::new()));

            if let UpdateEntry::Tree(t) = entry {
                ct = t;
            } else {
                panic!("blob already inserted");
            }
        }

        if ct.contains_key(file_name) {
            panic!("tree already inserted with same filename as blob");
        }

        ct.insert(file_name.to_owned(), UpdateEntry::Blob(oid));
    }

    fn create_updated(self, repo: &gix::Repository) -> gix::ObjectId {
        let head_tree = repo.head_commit().unwrap().tree().unwrap();
        Self::create_inner(self.update_tree, &head_tree, repo)
    }

    fn create_inner(
        tree: UpdateTree,
        current: &gix::Tree<'_>,
        repo: &gix::Repository,
    ) -> gix::ObjectId {
        use gix::objs::{
            tree::{Entry, EntryKind},
            Tree,
        };

        let mut nt = Tree::empty();
        let tree_ref = current.decode().unwrap();

        // Since they are stored in a btreemap we don't have to worry about
        // sorting here to satisfy the constraints of Tree
        for (name, entry) in tree {
            let filename = name.as_str().into();
            match entry {
                UpdateEntry::Blob(oid) => {
                    nt.entries.push(Entry {
                        mode: EntryKind::Blob.into(),
                        oid,
                        filename,
                    });
                }
                UpdateEntry::Tree(ut) => {
                    // Check if there is already an existing tree
                    let current_tree = tree_ref.entries.iter().find_map(|tre| {
                        if tre.filename == name && tre.mode.is_tree() {
                            Some(repo.find_object(tre.oid).unwrap().into_tree())
                        } else {
                            None
                        }
                    });
                    let current_tree = current_tree.unwrap_or_else(|| repo.empty_tree());

                    let oid = Self::create_inner(ut, &current_tree, repo);
                    nt.entries.push(Entry {
                        mode: EntryKind::Tree.into(),
                        oid,
                        filename,
                    });
                }
            }
        }

        // Insert all the entries from the old tree that weren't added/modified
        // in this builder
        for entry in tree_ref.entries {
            if let Err(i) = nt
                .entries
                .binary_search_by_key(&entry.filename, |e| e.filename.as_ref())
            {
                nt.entries.insert(
                    i,
                    Entry {
                        mode: entry.mode,
                        oid: entry.oid.into(),
                        filename: entry.filename.to_owned(),
                    },
                );
            }
        }

        repo.write_object(nt).unwrap().detach()
    }
}

/// For testing purposes we create a local git repository as the remote for tests
/// so that we avoid
///
/// 1. Using the crates.io git registry. It's massive and slow.
/// 2. Using some other external git registry, could fail for any number of
/// network etc related issues
/// 3. Needing to maintain a blessed remote of any kind
struct FakeRemote {
    repo: gix::Repository,
    td: utils::TempDir,
    // The parent commit
    parent: gix::ObjectId,
    commits: u32,
}

impl FakeRemote {
    fn new() -> Self {
        let td = utils::tempdir();

        let mut repo = gix::init_bare(&td).expect("failed to create remote repo");

        // Create an empty initial commit so we always have _something_
        let parent = {
            let empty_tree_id = repo
                .write_object(&gix::objs::Tree::empty())
                .unwrap()
                .detach();

            let repo = Self::snapshot(&mut repo);
            repo.commit(
                "HEAD",
                "initial commit",
                empty_tree_id,
                gix::commit::NO_PARENT_IDS,
            )
            .unwrap()
            .detach()
        };

        Self {
            td,
            repo,
            parent,
            commits: 0,
        }
    }

    #[inline]
    fn snapshot(repo: &mut gix::Repository) -> gix::config::CommitAutoRollback<'_> {
        let mut config = repo.config_snapshot_mut();
        config
            .set_raw_value("author", None, "name", "Integration Test")
            .unwrap();
        config
            .set_raw_value("committer", None, "name", "Integration Test")
            .unwrap();
        config
            .set_raw_value("author", None, "email", "tests@integration.se")
            .unwrap();
        config
            .set_raw_value("committer", None, "email", "tests@integration.se")
            .unwrap();

        // Disable GPG signing, it breaks testing if the user has it enabled
        config
            .set_raw_value("commit", None, "gpgsign", "false")
            .unwrap();

        config.commit_auto_rollback().unwrap()
    }

    fn commit(&mut self, krate: &IndexKrate) -> gix::ObjectId {
        let repo = Self::snapshot(&mut self.repo);

        let mut serialized = Vec::new();
        krate.write_json_lines(&mut serialized).unwrap();

        let name: tame_index::KrateName<'_> = krate.name().try_into().unwrap();
        let rel_path = tame_index::PathBuf::from(name.relative_path(None));

        let blob_id = repo.write_blob(serialized).unwrap().into();

        let mut tub = TreeUpdateBuilder::new();
        tub.upsert_blob(Path::new(&rel_path), blob_id);

        let tree_id = tub.create_updated(&repo);

        self.commits += 1;

        let parent = repo
            .commit(
                "HEAD",
                format!("{} - {}", krate.name(), self.commits),
                tree_id,
                [self.parent],
            )
            .unwrap()
            .detach();
        self.parent = parent;
        parent
    }

    fn local(&self) -> (RemoteGitIndex, utils::TempDir) {
        let td = utils::tempdir();

        let rgi = remote_index(&td, &self.td);

        (rgi, td)
    }
}

/// Validates we can clone a new index repo
#[test]
fn clones_new() {
    let remote = FakeRemote::new();
    let lock = &utils::unlocked();

    let (rgi, _td) = remote.local();

    assert!(rgi
        .cached_krate("clones_new".try_into().unwrap(), lock)
        .unwrap()
        .is_none());
}

/// Validates we can open an existing index repo
#[test]
fn opens_existing() {
    let mut remote = FakeRemote::new();
    let lock = &utils::unlocked();

    let krate = utils::fake_krate("opens-existing", 4);
    let expected_head = remote.commit(&krate);

    let (first, td) = remote.local();

    assert_eq!(
        first.local().head_commit().unwrap(),
        expected_head.to_hex().to_string()
    );

    // This should not be in the cache
    assert_eq!(
        first
            .krate("opens-existing".try_into().unwrap(), true, lock)
            .expect("failed to read git blob")
            .expect("expected krate"),
        krate,
    );

    let second = remote_index(&td, &remote.td);

    assert_eq!(
        second.local().head_commit().unwrap(),
        expected_head.to_hex().to_string()
    );

    // This should be in the cache as it is file based not memory based
    assert_eq!(
        first
            .cached_krate("opens-existing".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected cached krate"),
        krate,
    );
}

/// Validates that cache entries can be created and used
#[test]
fn updates_cache() {
    let mut remote = FakeRemote::new();
    let lock = &utils::unlocked();

    let krate = utils::fake_krate("updates-cache", 4);
    let expected_head = remote.commit(&krate);

    let (rgi, _td) = remote.local();

    assert_eq!(
        rgi.local().head_commit().unwrap(),
        expected_head.to_hex().to_string()
    );

    // This should not be in the cache
    assert_eq!(
        rgi.krate("updates-cache".try_into().unwrap(), true, lock)
            .expect("failed to read git blob")
            .expect("expected krate"),
        krate,
    );

    assert_eq!(
        rgi.cached_krate("updates-cache".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected krate"),
        krate,
    );
}

/// Validates we can fetch updates from the remote and invalidate only the cache
/// entries for the crates that have changed
#[test]
fn fetch_invalidates_cache() {
    let mut remote = FakeRemote::new();
    let lock = &utils::unlocked();

    let krate = utils::fake_krate("invalidates-cache", 4);
    let same = utils::fake_krate("will-be-cached", 2);
    remote.commit(&krate);
    let expected_head = remote.commit(&same);

    let (mut rgi, _td) = remote.local();

    assert_eq!(
        rgi.local().head_commit().unwrap(),
        expected_head.to_hex().to_string()
    );

    // These should not be in the cache
    assert_eq!(
        rgi.krate("invalidates-cache".try_into().unwrap(), true, lock)
            .expect("failed to read git blob")
            .expect("expected krate"),
        krate,
    );
    assert_eq!(
        rgi.krate("will-be-cached".try_into().unwrap(), true, lock)
            .expect("failed to read git blob")
            .expect("expected krate"),
        same,
    );

    // Update the remote
    let new_krate = utils::fake_krate("invalidates-cache", 5);
    let new_head = remote.commit(&new_krate);

    assert_eq!(
        rgi.cached_krate("invalidates-cache".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected krate"),
        krate,
    );
    assert_eq!(
        rgi.cached_krate("will-be-cached".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected krate"),
        same,
    );

    // Perform fetch, which should invalidate the cache
    rgi.fetch(lock).unwrap();

    assert_eq!(
        rgi.local().head_commit().unwrap(),
        new_head.to_hex().to_string()
    );

    assert!(rgi
        .cached_krate("invalidates-cache".try_into().unwrap(), lock)
        .unwrap()
        .is_none());

    assert_eq!(
        rgi.krate("invalidates-cache".try_into().unwrap(), true, lock)
            .expect("failed to read git blob")
            .expect("expected krate"),
        new_krate,
    );

    // This crate _should_ still be cached as it was not changed in the fetch
    assert_eq!(
        rgi.cached_krate("will-be-cached".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected krate"),
        same,
    );

    // We haven't made new commits, so the fetch should not move HEAD and thus
    // cache entries should still be valid
    rgi.fetch(lock).unwrap();

    assert_eq!(
        rgi.cached_krate("invalidates-cache".try_into().unwrap(), lock)
            .unwrap()
            .unwrap(),
        new_krate
    );

    let krate3 = utils::fake_krate("krate-3", 3);
    remote.commit(&krate3);

    let krate4 = utils::fake_krate("krate-4", 4);
    let expected_head = remote.commit(&krate4);

    rgi.fetch(lock).unwrap();

    assert_eq!(
        rgi.local().head_commit().unwrap(),
        expected_head.to_hex().to_string()
    );

    assert_eq!(
        rgi.cached_krate("invalidates-cache".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected krate"),
        new_krate,
    );
    assert_eq!(
        rgi.cached_krate("will-be-cached".try_into().unwrap(), lock)
            .expect("failed to read cache file")
            .expect("expected krate"),
        same,
    );
}

/// gix uses a default branch name of `main`, but most cargo git indexes on users
/// disks use the master branch, so just ensure that we support that as well
#[test]
fn non_main_local_branch() {
    let mut remote = FakeRemote::new();

    let local_td = utils::tempdir();

    // Set up the local repo as if it was an already existing index
    // created by cargo
    {
        // Do that actual init
        let mut cmd = std::process::Command::new("git");
        cmd.args(["init", "--bare", "-b", "master"]);
        cmd.arg(local_td.path());
        assert!(
            cmd.status().expect("failed to run git").success(),
            "git failed to init directory"
        );

        // Add a fake commit so that we have a local HEAD
        let mut repo = gix::open(local_td.path()).unwrap();

        let commit = {
            let snap = FakeRemote::snapshot(&mut repo);
            let empty_tree_id = snap
                .write_object(&gix::objs::Tree::empty())
                .unwrap()
                .detach();

            snap.commit(
                "refs/heads/master",
                "initial commit",
                empty_tree_id,
                gix::commit::NO_PARENT_IDS,
            )
            .unwrap()
            .detach()
        };

        use gix::refs::transaction as tx;
        repo.edit_references([
            tx::RefEdit {
                change: tx::Change::Update {
                    log: tx::LogChange {
                        mode: tx::RefLog::AndReference,
                        force_create_reflog: false,
                        message: "".into(),
                    },
                    expected: tx::PreviousValue::Any,
                    new: gix::refs::Target::Peeled(commit),
                },
                name: "refs/heads/master".try_into().unwrap(),
                deref: false,
            },
            tx::RefEdit {
                change: tx::Change::Update {
                    log: tx::LogChange {
                        mode: tx::RefLog::AndReference,
                        force_create_reflog: false,
                        message: "".into(),
                    },
                    expected: tx::PreviousValue::Any,
                    new: gix::refs::Target::Symbolic("refs/heads/master".try_into().unwrap()),
                },
                name: "HEAD".try_into().unwrap(),
                deref: false,
            },
        ])
        .unwrap();

        assert_eq!(commit, repo.head_commit().unwrap().id);
    }

    let mut rgi = remote_index(&local_td, &remote.td);
    let lock = &utils::unlocked();

    let first = utils::fake_krate("first", 1);
    remote.commit(&first);

    rgi.fetch(lock).unwrap();

    assert_eq!(
        rgi.krate("first".try_into().unwrap(), true, lock)
            .unwrap()
            .unwrap(),
        first
    );
}
