use crate::{
    extension::{Link, Signature},
    util::split_at_pos,
};

/// The signature of the link extension.
pub const SIGNATURE: Signature = *b"link";

/// Bitmaps to know which entries to delete or replace, even though details are still unknown.
#[derive(Clone)]
pub struct Bitmaps {
    /// A bitmap to signal which entries to delete, maybe.
    pub delete: gix_bitmap::ewah::Vec,
    /// A bitmap to signal which entries to replace, maybe.
    pub replace: gix_bitmap::ewah::Vec,
}

///
#[allow(clippy::empty_docs)]
pub mod decode {

    /// The error returned when decoding link extensions.
    #[derive(Debug, thiserror::Error)]
    #[allow(missing_docs)]
    pub enum Error {
        #[error("{0}")]
        Corrupt(&'static str),
        #[error("{kind} bitmap corrupt")]
        BitmapDecode {
            err: gix_bitmap::ewah::decode::Error,
            kind: &'static str,
        },
    }

    impl From<std::num::TryFromIntError> for Error {
        fn from(_: std::num::TryFromIntError) -> Self {
            Self::Corrupt("error in bitmap iteration trying to convert from u64 to usize")
        }
    }
}

pub(crate) fn decode(data: &[u8], object_hash: gix_hash::Kind) -> Result<Link, decode::Error> {
    let (id, data) = split_at_pos(data, object_hash.len_in_bytes())
        .ok_or(decode::Error::Corrupt(
            "link extension too short to read share index checksum",
        ))
        .map(|(id, d)| (gix_hash::ObjectId::from_bytes_or_panic(id), d))?;

    if data.is_empty() {
        return Ok(Link {
            shared_index_checksum: id,
            bitmaps: None,
        });
    }

    let (delete, data) =
        gix_bitmap::ewah::decode(data).map_err(|err| decode::Error::BitmapDecode { kind: "delete", err })?;
    let (replace, data) =
        gix_bitmap::ewah::decode(data).map_err(|err| decode::Error::BitmapDecode { kind: "replace", err })?;

    if !data.is_empty() {
        return Err(decode::Error::Corrupt("garbage trailing link extension"));
    }

    Ok(Link {
        shared_index_checksum: id,
        bitmaps: Some(Bitmaps { delete, replace }),
    })
}

impl Link {
    pub(crate) fn dissolve_into(
        self,
        split_index: &mut crate::File,
        object_hash: gix_hash::Kind,
        skip_hash: bool,
        options: crate::decode::Options,
    ) -> Result<(), crate::file::init::Error> {
        let shared_index_path = split_index
            .path
            .parent()
            .expect("split index file in .git folder")
            .join(format!("sharedindex.{}", self.shared_index_checksum));
        let mut shared_index = crate::File::at(
            shared_index_path,
            object_hash,
            skip_hash,
            crate::decode::Options {
                expected_checksum: self.shared_index_checksum.into(),
                ..options
            },
        )?;

        if let Some(bitmaps) = self.bitmaps {
            let mut split_entry_index = 0;

            let mut err = None;
            bitmaps.replace.for_each_set_bit(|replace_index| {
                let shared_entry = match shared_index.entries.get_mut(replace_index) {
                    Some(e) => e,
                    None => {
                        err = decode::Error::Corrupt("replace bitmap length exceeds shared index length - more entries in bitmap than found in shared index").into();
                        return None
                    }
                };

                if shared_entry.flags.contains(crate::entry::Flags::REMOVE) {
                    err = decode::Error::Corrupt("entry is marked as both replace and delete").into();
                    return None
                }

                let split_entry = match split_index.entries.get(split_entry_index) {
                    Some(e) => e,
                    None => {
                        err = decode::Error::Corrupt("replace bitmap length exceeds split index length - more entries in bitmap than found in split index").into();
                        return None
                    }
                };
                if !split_entry.path.is_empty() {
                    err = decode::Error::Corrupt("paths in split index entries that are for replacement should be empty").into();
                    return None
                }
                if shared_entry.path.is_empty() {
                    err = decode::Error::Corrupt("paths in shared index entries that are replaced should not be empty").into();
                    return None
                }
                shared_entry.stat = split_entry.stat;
                shared_entry.id = split_entry.id;
                shared_entry.flags = split_entry.flags;
                shared_entry.mode = split_entry.mode;

                split_entry_index += 1;
                Some(())
            });
            if let Some(err) = err {
                return Err(err.into());
            }

            let split_index_path_backing = std::mem::take(&mut split_index.path_backing);
            for mut split_entry in split_index.entries.drain(split_entry_index..) {
                let start = shared_index.path_backing.len();
                let split_index_path = split_entry.path.clone();

                split_entry.path = start..start + split_entry.path.len();
                shared_index.entries.push(split_entry);

                shared_index
                    .path_backing
                    .extend_from_slice(&split_index_path_backing[split_index_path]);
            }

            bitmaps.delete.for_each_set_bit(|delete_index| {
                let shared_entry = match shared_index.entries.get_mut(delete_index) {
                    Some(e) => e,
                    None => {
                        err = decode::Error::Corrupt("delete bitmap length exceeds shared index length - more entries in bitmap than found in shared index").into();
                        return None
                    }
                };
                shared_entry.flags.insert(crate::entry::Flags::REMOVE);
                Some(())
            });
            if let Some(err) = err {
                return Err(err.into());
            }

            shared_index
                .entries
                .retain(|e| !e.flags.contains(crate::entry::Flags::REMOVE));

            let mut shared_entries = std::mem::take(&mut shared_index.entries);
            shared_entries.sort_by(|a, b| a.cmp(b, &shared_index.state));

            split_index.entries = shared_entries;
            split_index.path_backing = std::mem::take(&mut shared_index.path_backing);
        }

        Ok(())
    }
}
