import { describe, it, expect } from 'vitest';
import { computeDecayedRelevance, boostRelevance } from '../decay.js';

describe('computeDecayedRelevance', () => {
  it('returns original relevance for just-created memory', () => {
    const now = new Date();
    expect(computeDecayedRelevance(0.8, now.toISOString(), 30, now)).toBeCloseTo(0.8);
  });

  it('halves relevance after exactly one half-life', () => {
    const now = new Date();
    const thirtyDaysAgo = new Date(now.getTime() - 30 * 86_400_000);
    expect(computeDecayedRelevance(1.0, thirtyDaysAgo.toISOString(), 30, now)).toBeCloseTo(0.5, 2);
  });

  it('quarters relevance after two half-lives', () => {
    const now = new Date();
    const sixtyDaysAgo = new Date(now.getTime() - 60 * 86_400_000);
    expect(computeDecayedRelevance(1.0, sixtyDaysAgo.toISOString(), 30, now)).toBeCloseTo(0.25, 2);
  });

  it('returns 0 for zero relevance', () => {
    expect(computeDecayedRelevance(0, '2024-01-01')).toBe(0);
  });

  it('clamps to [0, 1]', () => {
    const now = new Date();
    expect(computeDecayedRelevance(1.5, now.toISOString(), 30, now)).toBeLessThanOrEqual(1);
  });

  it('returns original relevance for zero half-life', () => {
    expect(computeDecayedRelevance(0.8, '2024-01-01', 0)).toBe(0.8);
  });

  it('accepts Date objects', () => {
    const now = new Date();
    expect(computeDecayedRelevance(0.8, now, 30, now)).toBeCloseTo(0.8);
  });
});

describe('boostRelevance', () => {
  it('boosts relevance toward 1.0', () => {
    expect(boostRelevance(0.5, 0.3)).toBeCloseTo(0.65);
  });

  it('does not exceed 1.0', () => {
    expect(boostRelevance(0.99, 0.5)).toBeLessThanOrEqual(1.0);
  });

  it('returns 0 for zero relevance with zero boost', () => {
    expect(boostRelevance(0, 0)).toBe(0);
  });

  it('applies default boost factor of 0.3', () => {
    expect(boostRelevance(0.5)).toBeCloseTo(0.65);
  });
});
