use crate::store::{db_decode, db_encode, Row};
use bitcoin_hashes::Hash;
use bitcoincash::Txid;

use super::DBRow;

const HEIGHTINDEX_CF: &str = "height";

#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct HeightIndexKey {
    pub txid: [u8; 32],
}

#[derive(Debug)]
pub struct HeightIndexRow {
    pub key: HeightIndexKey,
    height: u32,
}

impl HeightIndexRow {
    pub fn new(txid: &Txid, height: u32) -> HeightIndexRow {
        HeightIndexRow {
            key: HeightIndexKey {
                txid: txid.into_inner(),
            },
            height,
        }
    }

    pub fn filter_by_txid(txid: &Txid) -> Vec<u8> {
        txid.to_vec()
    }

    pub fn txid(&self) -> Txid {
        Txid::from_inner(self.key.txid)
    }

    pub fn height(&self) -> u32 {
        self.height
    }

    /**
     * For fetching the height without deserializing the full row object.
     */
    pub fn height_from_dbvalue(value: &[u8]) -> u32 {
        db_decode(value).expect("failed to deserialize height")
    }
}

impl DBRow for HeightIndexRow {
    const CF: &'static str = HEIGHTINDEX_CF;
    fn to_row(&self) -> Row {
        Row {
            key: db_encode(&self.key).unwrap().into_boxed_slice(),
            value: db_encode(&self.height).unwrap().into_boxed_slice(),
        }
    }

    fn from_row(row: &Row) -> HeightIndexRow {
        HeightIndexRow {
            key: db_decode(&row.key).expect("failed to parse TxKey"),
            height: db_decode(&row.value).expect("failed to parse height"),
        }
    }
}
