// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation: version 2 of the License, dated June 1991.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see <https://www.gnu.org/licenses/>.

use std::error::Error;
use std::fmt::{self, Debug, Display};
use std::io::{self, Write};
use std::os::raw::c_void;

pub const GIT_MAX_RAWSZ: usize = 32;

/// An error indicating an invalid hash algorithm.
///
/// The contained `u32` is the same as the `algo` field in `ObjectID`.
#[derive(Debug, Copy, Clone)]
pub struct InvalidHashAlgorithm(pub u32);

impl Display for InvalidHashAlgorithm {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "invalid hash algorithm {}", self.0)
    }
}

impl Error for InvalidHashAlgorithm {}

/// A binary object ID.
#[repr(C)]
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct ObjectID {
    pub hash: [u8; GIT_MAX_RAWSZ],
    pub algo: u32,
}

#[allow(dead_code)]
impl ObjectID {
    /// Return a new object ID with the given algorithm and hash.
    ///
    /// `hash` must be exactly the proper length for `algo` and this function panics if it is not.
    /// The extra internal storage of `hash`, if any, is zero filled.
    pub fn new(algo: HashAlgorithm, hash: &[u8]) -> Self {
        let mut data = [0u8; GIT_MAX_RAWSZ];
        // This verifies that the length of `hash` is correct.
        data[0..algo.raw_len()].copy_from_slice(hash);
        Self {
            hash: data,
            algo: algo as u32,
        }
    }

    /// Return the algorithm for this object ID.
    ///
    /// If the algorithm set internally is not valid, this function panics.
    pub fn algo(&self) -> Result<HashAlgorithm, InvalidHashAlgorithm> {
        HashAlgorithm::from_u32(self.algo).ok_or(InvalidHashAlgorithm(self.algo))
    }

    pub fn as_slice(&self) -> Result<&[u8], InvalidHashAlgorithm> {
        match HashAlgorithm::from_u32(self.algo) {
            Some(algo) => Ok(&self.hash[0..algo.raw_len()]),
            None => Err(InvalidHashAlgorithm(self.algo)),
        }
    }

    pub fn as_mut_slice(&mut self) -> Result<&mut [u8], InvalidHashAlgorithm> {
        match HashAlgorithm::from_u32(self.algo) {
            Some(algo) => Ok(&mut self.hash[0..algo.raw_len()]),
            None => Err(InvalidHashAlgorithm(self.algo)),
        }
    }
}

impl Display for ObjectID {
    /// Format this object ID as a hex object ID.
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let hash = self.as_slice().unwrap();
        for x in hash {
            write!(f, "{:02x}", x)?;
        }
        Ok(())
    }
}

impl Debug for ObjectID {
    /// Format this object ID as a hex object ID with a colon and name appended to it.
    ///
    /// ```
    /// assert_eq!(
    ///     format!("{:?}", HashAlgorithm::SHA256.null_oid()),
    ///     "0000000000000000000000000000000000000000000000000000000000000000:sha256"
    /// );
    /// ```
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let hash = match self.as_slice() {
            Ok(hash) => hash,
            Err(_) => &self.hash,
        };
        for x in hash {
            write!(f, "{:02x}", x)?;
        }
        match self.algo() {
            Ok(algo) => write!(f, ":{}", algo.name()),
            Err(e) => write!(f, ":invalid-hash-algo-{}", e.0),
        }
    }
}

/// A trait to implement hashing with a cryptographic algorithm.
pub trait CryptoDigest {
    /// Return true if this digest is safe for use with untrusted data, false otherwise.
    fn is_safe(&self) -> bool;

    /// Update the digest with the specified data.
    fn update(&mut self, data: &[u8]);

    /// Return an object ID, consuming the hasher.
    fn into_oid(self) -> ObjectID;

    /// Return a hash as a `Vec`, consuming the hasher.
    fn into_vec(self) -> Vec<u8>;
}

/// A structure to hash data with a cryptographic hash algorithm.
///
/// Instances of this class are safe for use with untrusted data, provided Git has been compiled
/// with a collision-detecting implementation of SHA-1.
pub struct CryptoHasher {
    algo: HashAlgorithm,
    ctx: *mut c_void,
}

impl CryptoHasher {
    /// Create a new hasher with the algorithm specified with `algo`.
    ///
    /// This hasher is safe to use on untrusted data.  If SHA-1 is selected and Git was compiled
    /// with a collision-detecting implementation of SHA-1, then this function will use that
    /// implementation and detect any attempts at a collision.
    pub fn new(algo: HashAlgorithm) -> Self {
        let ctx = unsafe { c::git_hash_alloc() };
        unsafe { c::git_hash_init(ctx, algo.hash_algo_ptr()) };
        Self { algo, ctx }
    }
}

impl CryptoDigest for CryptoHasher {
    /// Return true if this digest is safe for use with untrusted data, false otherwise.
    fn is_safe(&self) -> bool {
        true
    }

    /// Update the hasher with the specified data.
    fn update(&mut self, data: &[u8]) {
        unsafe { c::git_hash_update(self.ctx, data.as_ptr() as *const c_void, data.len()) };
    }

    /// Return an object ID, consuming the hasher.
    fn into_oid(self) -> ObjectID {
        let mut oid = ObjectID {
            hash: [0u8; 32],
            algo: self.algo as u32,
        };
        unsafe { c::git_hash_final_oid(&mut oid as *mut ObjectID as *mut c_void, self.ctx) };
        oid
    }

    /// Return a hash as a `Vec`, consuming the hasher.
    fn into_vec(self) -> Vec<u8> {
        let mut v = vec![0u8; self.algo.raw_len()];
        unsafe { c::git_hash_final(v.as_mut_ptr(), self.ctx) };
        v
    }
}

impl Clone for CryptoHasher {
    fn clone(&self) -> Self {
        let ctx = unsafe { c::git_hash_alloc() };
        unsafe {
            c::git_hash_init(ctx, self.algo.hash_algo_ptr());
            c::git_hash_clone(ctx, self.ctx)
        };
        Self {
            algo: self.algo,
            ctx,
        }
    }
}

impl Drop for CryptoHasher {
    fn drop(&mut self) {
        unsafe {
            c::git_hash_discard(self.ctx);
            c::git_hash_free(self.ctx);
        };
    }
}

impl Write for CryptoHasher {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        self.update(data);
        Ok(data.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

/// A hash algorithm,
#[repr(C)]
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum HashAlgorithm {
    SHA1 = 1,
    SHA256 = 2,
}

#[allow(dead_code)]
impl HashAlgorithm {
    const SHA1_NULL_OID: ObjectID = ObjectID {
        hash: [0u8; 32],
        algo: Self::SHA1 as u32,
    };
    const SHA256_NULL_OID: ObjectID = ObjectID {
        hash: [0u8; 32],
        algo: Self::SHA256 as u32,
    };

    const SHA1_EMPTY_TREE: ObjectID = ObjectID {
        hash: *b"\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
        algo: Self::SHA1 as u32,
    };
    const SHA256_EMPTY_TREE: ObjectID = ObjectID {
        hash: *b"\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc\x53\x21",
        algo: Self::SHA256 as u32,
    };

    const SHA1_EMPTY_BLOB: ObjectID = ObjectID {
        hash: *b"\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
        algo: Self::SHA1 as u32,
    };
    const SHA256_EMPTY_BLOB: ObjectID = ObjectID {
        hash: *b"\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72\x18\x13",
        algo: Self::SHA256 as u32,
    };

    /// Return a hash algorithm based on the internal integer ID used by Git.
    ///
    /// Returns `None` if the algorithm doesn't indicate a valid algorithm.
    pub const fn from_u32(algo: u32) -> Option<HashAlgorithm> {
        match algo {
            1 => Some(HashAlgorithm::SHA1),
            2 => Some(HashAlgorithm::SHA256),
            _ => None,
        }
    }

    /// Return a hash algorithm based on the internal integer ID used by Git.
    ///
    /// Returns `None` if the algorithm doesn't indicate a valid algorithm.
    pub const fn from_format_id(algo: u32) -> Option<HashAlgorithm> {
        match algo {
            0x73686131 => Some(HashAlgorithm::SHA1),
            0x73323536 => Some(HashAlgorithm::SHA256),
            _ => None,
        }
    }

    /// The name of this hash algorithm as a string suitable for the configuration file.
    pub const fn name(self) -> &'static str {
        match self {
            HashAlgorithm::SHA1 => "sha1",
            HashAlgorithm::SHA256 => "sha256",
        }
    }

    /// The format ID of this algorithm for binary formats.
    ///
    /// Note that when writing this to a data format, it should be written in big-endian format
    /// explicitly.
    pub const fn format_id(self) -> u32 {
        match self {
            HashAlgorithm::SHA1 => 0x73686131,
            HashAlgorithm::SHA256 => 0x73323536,
        }
    }

    /// The length of binary object IDs in this algorithm in bytes.
    pub const fn raw_len(self) -> usize {
        match self {
            HashAlgorithm::SHA1 => 20,
            HashAlgorithm::SHA256 => 32,
        }
    }

    /// The length of object IDs in this algorithm in hexadecimal characters.
    pub const fn hex_len(self) -> usize {
        self.raw_len() * 2
    }

    /// The number of bytes which is processed by one iteration of this algorithm's compression
    /// function.
    pub const fn block_size(self) -> usize {
        match self {
            HashAlgorithm::SHA1 => 64,
            HashAlgorithm::SHA256 => 64,
        }
    }

    /// The object ID representing the empty blob.
    pub const fn empty_blob(self) -> &'static ObjectID {
        match self {
            HashAlgorithm::SHA1 => &Self::SHA1_EMPTY_BLOB,
            HashAlgorithm::SHA256 => &Self::SHA256_EMPTY_BLOB,
        }
    }

    /// The object ID representing the empty tree.
    pub const fn empty_tree(self) -> &'static ObjectID {
        match self {
            HashAlgorithm::SHA1 => &Self::SHA1_EMPTY_TREE,
            HashAlgorithm::SHA256 => &Self::SHA256_EMPTY_TREE,
        }
    }

    /// The object ID which is all zeros.
    pub const fn null_oid(self) -> &'static ObjectID {
        match self {
            HashAlgorithm::SHA1 => &Self::SHA1_NULL_OID,
            HashAlgorithm::SHA256 => &Self::SHA256_NULL_OID,
        }
    }

    /// A pointer to the C `struct git_hash_algo` for interoperability with C.
    pub fn hash_algo_ptr(self) -> *const c_void {
        unsafe { c::hash_algo_ptr_by_number(self as u32) }
    }

    /// Create a hasher for this algorithm.
    pub fn hasher(self) -> CryptoHasher {
        CryptoHasher::new(self)
    }
}

pub mod c {
    use std::os::raw::c_void;

    extern "C" {
        pub fn hash_algo_ptr_by_number(n: u32) -> *const c_void;
        pub fn unsafe_hash_algo(algop: *const c_void) -> *const c_void;
        pub fn git_hash_alloc() -> *mut c_void;
        pub fn git_hash_free(ctx: *mut c_void);
        pub fn git_hash_init(dst: *mut c_void, algop: *const c_void);
        pub fn git_hash_clone(dst: *mut c_void, src: *const c_void);
        pub fn git_hash_update(ctx: *mut c_void, inp: *const c_void, len: usize);
        pub fn git_hash_final(hash: *mut u8, ctx: *mut c_void);
        pub fn git_hash_discard(ctx: *mut c_void);
        pub fn git_hash_final_oid(hash: *mut c_void, ctx: *mut c_void);
    }
}

#[cfg(test)]
mod tests {
    use super::{CryptoDigest, HashAlgorithm, ObjectID};
    use std::io::Write;

    fn all_algos() -> &'static [HashAlgorithm] {
        &[HashAlgorithm::SHA1, HashAlgorithm::SHA256]
    }

    #[test]
    fn format_id_round_trips() {
        for algo in all_algos() {
            assert_eq!(
                *algo,
                HashAlgorithm::from_format_id(algo.format_id()).unwrap()
            );
        }
    }

    #[test]
    fn offset_round_trips() {
        for algo in all_algos() {
            assert_eq!(*algo, HashAlgorithm::from_u32(*algo as u32).unwrap());
        }
    }

    #[test]
    fn slices_have_correct_length() {
        for algo in all_algos() {
            for oid in [algo.null_oid(), algo.empty_blob(), algo.empty_tree()] {
                assert_eq!(oid.as_slice().unwrap().len(), algo.raw_len());
            }
        }
    }

    #[test]
    fn object_ids_format_correctly() {
        let entries = &[
            (
                HashAlgorithm::SHA1.null_oid(),
                "0000000000000000000000000000000000000000",
                "0000000000000000000000000000000000000000:sha1",
            ),
            (
                HashAlgorithm::SHA1.empty_blob(),
                "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
                "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391:sha1",
            ),
            (
                HashAlgorithm::SHA1.empty_tree(),
                "4b825dc642cb6eb9a060e54bf8d69288fbee4904",
                "4b825dc642cb6eb9a060e54bf8d69288fbee4904:sha1",
            ),
            (
                HashAlgorithm::SHA256.null_oid(),
                "0000000000000000000000000000000000000000000000000000000000000000",
                "0000000000000000000000000000000000000000000000000000000000000000:sha256",
            ),
            (
                HashAlgorithm::SHA256.empty_blob(),
                "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813",
                "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813:sha256",
            ),
            (
                HashAlgorithm::SHA256.empty_tree(),
                "6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321",
                "6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321:sha256",
            ),
        ];
        for (oid, display, debug) in entries {
            assert_eq!(format!("{}", oid), *display);
            assert_eq!(format!("{:?}", oid), *debug);
        }
    }

    #[test]
    fn hasher_works_correctly() {
        for algo in all_algos() {
            let tests: &[(&[u8], &ObjectID)] = &[
                (b"blob 0\0", algo.empty_blob()),
                (b"tree 0\0", algo.empty_tree()),
            ];
            for (data, oid) in tests {
                let mut h = algo.hasher();
                assert!(h.is_safe());
                // Test that this works incrementally.
                h.update(&data[0..2]);
                h.update(&data[2..]);

                let h2 = h.clone();
                let h3 = h2.clone();

                let actual_oid = h.into_oid();
                assert_eq!(**oid, actual_oid);

                let v = h2.into_vec();
                assert_eq!((*oid).as_slice().unwrap(), &v);

                let mut h = algo.hasher();
                h.write_all(&data[0..2]).unwrap();
                h.write_all(&data[2..]).unwrap();

                let actual_oid = h.into_oid();
                assert_eq!(**oid, actual_oid);
                std::mem::drop(h3);
            }
        }
    }
}
