use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Bitcoin, Dollars, StoredF64};
use vecdb::{Exit, ReadableVec};
use super::super::activity;
use super::Vecs;
use crate::{distribution, price};
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
prices: &price::Vecs,
distribution: &distribution::Vecs,
activity: &activity::Vecs,
exit: &Exit,
) -> Result<()> {
let starting_height = indexer.safe_lengths().height;
let all_metrics = &distribution.utxo_cohorts.all.metrics;
let coinblocks_destroyed = &distribution.coinblocks_destroyed;
let coindays_destroyed = &all_metrics.activity.coindays_destroyed;
let circulating_supply = &all_metrics.supply.total.btc.height;
self.destroyed
.cumulative
.height
.compute_cumulative_transformed_binary(
starting_height,
&prices.spot.usd.height,
&coinblocks_destroyed.block,
|price, value| StoredF64::from(f64::from(price) * f64::from(value)),
exit,
)?;
self.created
.cumulative
.height
.compute_cumulative_transformed_binary(
starting_height,
&prices.spot.usd.height,
&activity.coinblocks_created.block,
|price, value| StoredF64::from(f64::from(price) * f64::from(value)),
exit,
)?;
self.stored
.cumulative
.height
.compute_cumulative_transformed_binary(
starting_height,
&prices.spot.usd.height,
&activity.coinblocks_stored.block,
|price, value| StoredF64::from(f64::from(price) * f64::from(value)),
exit,
)?;
let mut cumulative = None;
self.vocdd.cumulative.height.compute_transform3(
starting_height,
&prices.spot.usd.height,
&coindays_destroyed.block,
circulating_supply,
|(i, price, cdd, supply, this): (_, Dollars, StoredF64, Bitcoin, _)| {
let cumulative = cumulative.get_or_insert_with(|| {
i.decremented()
.and_then(|height| this.collect_one(height))
.unwrap_or_default()
});
let supply_f64 = f64::from(supply);
let value = if supply_f64 == 0.0 {
StoredF64::from(0.0)
} else {
StoredF64::from(f64::from(price) * f64::from(cdd) / supply_f64)
};
*cumulative += value;
(i, *cumulative)
},
exit,
)?;
Ok(())
}
}