/*
 * Copyright (C) 2022 StApps
 * 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 3.
 *
 * 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/>.
 */
import {findRRules, RRule} from './ical';
import moment, {unitOfTime} from 'moment';
import {SCISO8601Date} from '@openstapps/core';
import {shuffle} from '@openstapps/collection-utils';

/**
 *
 */
function expandRRule(rule: RRule): SCISO8601Date[] {
  const initial = moment(rule.from);
  const interval = rule.interval ?? 1;

  return shuffle(
    Array.from({
      length: Math.floor(moment(rule.until).diff(initial, rule.freq, true) / interval) + 1,
    }).map((_, i) =>
      initial
        .clone()
        .add(interval * i, rule.freq ?? 'day')
        .toISOString(),
    ),
  );
}

describe('iCal', () => {
  it('should find simple recurrence patterns', () => {
    for (const freq of ['day', 'week', 'month', 'year'] as unitOfTime.Diff[]) {
      for (const interval of [1, 2, 3]) {
        const pattern: RRule = {
          freq: freq,
          interval: interval,
          from: moment('2021-09-01T10:00').toISOString(),
          until: moment('2021-09-01T10:00')
            .add(4 * interval, freq)
            .toISOString(),
        };

        expect(findRRules(expandRRule(pattern))).toEqual([pattern]);
      }
    }
  });

  it('should find missing recurrence patterns', () => {
    const pattern: SCISO8601Date = moment('2021-09-01T10:00').toISOString();

    expect(findRRules([pattern])).toEqual([pattern]);
  });

  it('should find mixed recurrence patterns', () => {
    const singlePattern: SCISO8601Date = moment('2021-09-01T09:00').toISOString();

    const weeklyPattern: RRule = {
      freq: 'week',
      interval: 1,
      from: moment('2021-09-03T10:00').toISOString(),
      until: moment('2021-09-03T10:00').add(4, 'weeks').toISOString(),
    };

    expect(findRRules(shuffle([singlePattern, ...expandRRule(weeklyPattern)]))).toEqual([
      singlePattern,
      weeklyPattern,
    ]);
  });
});
