import expect from 'expect';
import {
  isTreatmentBasedOnRoll,
  getActiveExperimentGroup,
  getRandomValue,
} from 'mweb/common/utils/experimentUtils';
import {
  ExperimentUUIDs,
  ExperimentNames,
  ExperimentMetadata,
  ExperimentGroups,
} from 'mweb/common/actions/experiments';

describe('getRandomValue', () => {
  it('reproduces known good values from provided inputs', () => {
    const experimentUUID = '44dbd670-63e6-4f7f-aa47-417f3eccd939';
    const deviceID = '3bc1a61b8c3ab036';
    expect(getRandomValue(experimentUUID, deviceID)).toEqual(
      0.07280236668884754,
    );
  });
});

const metadata: ExperimentMetadata = {
  uuid: ExperimentUUIDs.Test,
  name: ExperimentNames.Test,
  groups: [
    {
      value: ExperimentGroups.Treatment,
      weight: 5,
    },
    {
      value: ExperimentGroups.Control,
      weight: 95,
    },
  ],
};

describe('isTreatmentBasedOnRoll', () => {
  it('returns true if roll is less than treatmentWeight / totalWeight ', () => {
    expect(isTreatmentBasedOnRoll(metadata, 0)).toBeTruthy();
    expect(isTreatmentBasedOnRoll(metadata, 0.049)).toBeTruthy();
  });

  it('returns false if roll is greater than or equal to treatmentWeight / totalWeight ', () => {
    expect(isTreatmentBasedOnRoll(metadata, 0.05)).toBeFalsy();
    expect(isTreatmentBasedOnRoll(metadata, 1)).toBeFalsy();
  });

  it('plays nicely with weights that do not add up to 100', () => {
    const metadata2: ExperimentMetadata = {
      uuid: ExperimentUUIDs.Test,
      name: ExperimentNames.Test,
      groups: [
        {
          value: ExperimentGroups.Treatment,
          weight: 0.5,
        },
        {
          value: ExperimentGroups.Control,
          weight: 0.5,
        },
      ],
    };

    expect(isTreatmentBasedOnRoll(metadata2, 0.4)).toBeTruthy();
    expect(isTreatmentBasedOnRoll(metadata2, 0.5)).toBeFalsy();
    expect(isTreatmentBasedOnRoll(metadata2, 0.8)).toBeFalsy();
  });
});

describe('getActiveExperimentGroup', () => {
  // The fact that these map to the correct groups is entirely coincidental.
  const controlBucket = 'control';
  const treatmentBucket = 'treatment';

  it('gives the correct group for each bucket', () => {
    expect(getActiveExperimentGroup(metadata, controlBucket, {})).toEqual(
      ExperimentGroups.Control,
    );
    expect(getActiveExperimentGroup(metadata, treatmentBucket, {})).toEqual(
      ExperimentGroups.Treatment,
    );
  });

  it('gives the correct group for each overridden bucket', () => {
    expect(
      getActiveExperimentGroup(metadata, controlBucket, {
        [ExperimentUUIDs.Test]: ExperimentGroups.Treatment,
      }),
    ).toEqual(ExperimentGroups.Treatment);
    expect(
      getActiveExperimentGroup(metadata, controlBucket, {
        [ExperimentUUIDs.Test]: ExperimentGroups.Control,
      }),
    ).toEqual(ExperimentGroups.Control);
    expect(
      getActiveExperimentGroup(metadata, treatmentBucket, {
        [ExperimentUUIDs.Test]: ExperimentGroups.Treatment,
      }),
    ).toEqual(ExperimentGroups.Treatment);
    expect(
      getActiveExperimentGroup(metadata, treatmentBucket, {
        [ExperimentUUIDs.Test]: ExperimentGroups.Control,
      }),
    ).toEqual(ExperimentGroups.Control);
  });
});
