import { describe, expect, it } from 'vitest';

import {
    RacingDomainValidationError,
} from '../errors/RacingDomainError';
import {
    SeasonDropPolicy,
    type SeasonDropStrategy,
} from './SeasonDropPolicy';

describe('SeasonDropPolicy', () => {
  it('allows strategy "none" with undefined n', () => {
    const policy = new SeasonDropPolicy({ strategy: 'none' });

    expect(policy.strategy).toBe('none');
    expect(policy.n).toBeUndefined();
  });

  it('throws when strategy "none" has n defined', () => {
    expect(
      () =>
        new SeasonDropPolicy({
          strategy: 'none',
          n: 1,
        }),
    ).toThrow(RacingDomainValidationError);
  });

  it('requires positive integer n for "bestNResults" and "dropWorstN"', () => {
    const strategies: SeasonDropStrategy[] = ['bestNResults', 'dropWorstN'];

    for (const strategy of strategies) {
      expect(
        () =>
          new SeasonDropPolicy({
            strategy,
            n: 0,
          }),
      ).toThrow(RacingDomainValidationError);

      expect(
        () =>
          new SeasonDropPolicy({
            strategy,
            n: -1,
          }),
      ).toThrow(RacingDomainValidationError);
    }

    const okBest = new SeasonDropPolicy({
      strategy: 'bestNResults',
      n: 3,
    });
    const okDrop = new SeasonDropPolicy({
      strategy: 'dropWorstN',
      n: 2,
    });

    expect(okBest.n).toBe(3);
    expect(okDrop.n).toBe(2);
  });

  it('equals compares strategy and n', () => {
    const a = new SeasonDropPolicy({ strategy: 'none' });
    const b = new SeasonDropPolicy({ strategy: 'none' });
    const c = new SeasonDropPolicy({ strategy: 'bestNResults', n: 3 });

    expect(a.equals(b)).toBe(true);
    expect(a.equals(c)).toBe(false);
  });
});