/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package org.apache.unomi.itests;

import org.apache.unomi.api.Event;
import org.apache.unomi.api.Metadata;
import org.apache.unomi.api.Profile;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.api.exceptions.BadSegmentConditionException;
import org.apache.unomi.api.rules.Rule;
import org.apache.unomi.api.segments.Scoring;
import org.apache.unomi.api.segments.ScoringElement;
import org.apache.unomi.api.segments.Segment;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.ProfileService;
import org.apache.unomi.api.services.SegmentService;
import org.apache.unomi.persistence.spi.PersistenceService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerSuite;
import org.ops4j.pax.exam.util.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerSuite.class)
public class SegmentIT extends BaseIT {
    private final static Logger LOGGER = LoggerFactory.getLogger(SegmentIT.class);
    private final static String SEGMENT_ID = "test-segment-id-2";

    @Inject
    @Filter(timeout = 600000)
    protected SegmentService segmentService;

    @Inject
    @Filter(timeout = 600000)
    protected ProfileService profileService;

    @Inject
    @Filter(timeout = 600000)
    protected EventService eventService;

    @Inject
    @Filter(timeout = 600000)
    protected PersistenceService persistenceService;

    @Before
    public void setUp() throws InterruptedException {
        removeItems(Segment.class);
        removeItems(Scoring.class);
    }

    @After
    public void tearDown() throws InterruptedException {
        removeItems(Segment.class);
        removeItems(Scoring.class);
        removeItems(Profile.class);
        removeItems(Event.class);
    }

    @Test
    public void testSegments() {
        Assert.assertNotNull("Segment service should be available", segmentService);
        List<Metadata> segmentMetadatas = segmentService.getSegmentMetadatas(0, 50, null).getList();
        Assert.assertEquals("Segment metadata list should be empty", 0, segmentMetadatas.size());
        LOGGER.info("Retrieved " + segmentMetadatas.size() + " segment metadata entries");
    }

    @Test(expected = BadSegmentConditionException.class)
    public void testSegmentWithNullCondition() {
        Metadata segmentMetadata = new Metadata(SEGMENT_ID);
        Segment segment = new Segment();
        segment.setMetadata(segmentMetadata);
        segment.setCondition(null);

        segmentService.setSegmentDefinition(segment);
    }

    @Test
    public void testSegmentWithNullConditionButDisabled() {
        Metadata segmentMetadata = new Metadata(SEGMENT_ID);
        segmentMetadata.setEnabled(false);
        Segment segment = new Segment();
        segment.setMetadata(segmentMetadata);
        segment.setCondition(null);

        segmentService.setSegmentDefinition(segment);
        segmentService.removeSegmentDefinition(SEGMENT_ID, false);
    }

    @Test(expected = BadSegmentConditionException.class)
    public void testSegmentWithInValidCondition() {
        Metadata segmentMetadata = new Metadata(SEGMENT_ID);
        Segment segment = new Segment();
        segment.setMetadata(segmentMetadata);
        Condition condition = new Condition();
        condition.setParameter("param", "param value");
        condition.setConditionTypeId("fakeConditionId");
        segment.setCondition(condition);

        segmentService.setSegmentDefinition(segment);
    }

    @Test(expected = BadSegmentConditionException.class)
    public void testSegmentWithInvalidConditionParameterTypes() {
        Metadata segmentMetadata = new Metadata(SEGMENT_ID);
        Segment segment = new Segment(segmentMetadata);
        Condition segmentCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        segmentCondition.setParameter("minimumEventCount", "2");
        segmentCondition.setParameter("numberOfDays", "10");
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        segmentCondition.setParameter("eventCondition", pastEventEventCondition);
        segment.setCondition(segmentCondition);
        segmentService.setSegmentDefinition(segment);
    }

    @Test
    public void testSegmentWithValidCondition() {
        Metadata segmentMetadata = new Metadata(SEGMENT_ID);
        Segment segment = new Segment(segmentMetadata);
        Condition segmentCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        segmentCondition.setParameter("minimumEventCount", 2);
        segmentCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        segmentCondition.setParameter("eventCondition", pastEventEventCondition);
        segment.setCondition(segmentCondition);
        segmentService.setSegmentDefinition(segment);

        segmentService.removeSegmentDefinition(SEGMENT_ID, false);
    }

    @Test
    public void testProfileEngagedSegmentAddedRemoved() throws InterruptedException {
        Condition segmentSearchCondition = new Condition();
        segmentSearchCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
        segmentSearchCondition.setParameter("propertyName", "segments");
        segmentSearchCondition.setParameter("comparisonOperator", "equals");
        segmentSearchCondition.setParameter("propertyValue", "add-delete-segment-test");

        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profile.setProperty("age", 42);
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null);

        keepTrying("Profile should not be engaged in the segment yet", () -> persistenceService.query(segmentSearchCondition, null, Profile.class),
                profiles -> profiles.size() == 0, 1000, 20);

        // create the segment
        Metadata segmentMetadata = new Metadata("add-delete-segment-test");
        Segment segment = new Segment(segmentMetadata);
        Condition segmentCondition = new Condition(definitionsService.getConditionType("profilePropertyCondition"));
        segmentCondition.setParameter("propertyName", "properties.age");
        segmentCondition.setParameter("comparisonOperator", "exists");
        segment.setCondition(segmentCondition);
        segmentService.setSegmentDefinition(segment);

        // insure the profile that did the past event condition is correctly engaged in the segment.
        keepTrying("Profile should be engaged in the segment", () -> persistenceService.query(segmentSearchCondition, null, Profile.class),
                profiles -> profiles.size() == 1, 1000, 20);

        // delete the segment
        segmentService.removeSegmentDefinition("add-delete-segment-test", false);

        // insure the profile is not engaged anymore after segment deleted
        keepTrying("Profile should not be engaged in the segment anymore after the segment have been deleted", () -> persistenceService.query(segmentSearchCondition, null, Profile.class),
                profiles -> profiles.size() == 0, 1000, 20);
    }

    @Test
    public void testSegmentWithPastEventCondition() throws InterruptedException {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // send event for profile from a previous date (today -3 days)
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        Event testEvent = new Event("test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        int changes = eventService.send(testEvent);
        if ((changes & EventService.PROFILE_UPDATED) == EventService.PROFILE_UPDATED) {
            profileService.save(profile);
            persistenceService.refreshIndex(Profile.class, null);
        }
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // create the segment
        Metadata segmentMetadata = new Metadata("past-event-segment-test");
        Segment segment = new Segment(segmentMetadata);
        Condition segmentCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        segmentCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        segmentCondition.setParameter("eventCondition", pastEventEventCondition);
        segment.setCondition(segmentCondition);
        segmentService.setSegmentDefinition(segment);

        // insure the profile that did the past event condition is correctly engaged in the segment.
        keepTrying("Profile should be engaged in the segment", () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getSegments().contains("past-event-segment-test"), 1000, 20);
    }

    @Test
    public void testSegmentWithNegativePastEventCondition() throws InterruptedException {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // create the negative past event condition segment
        Metadata segmentMetadata = new Metadata("negative-past-event-segment-test");
        Segment segment = new Segment(segmentMetadata);
        Condition segmentCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        segmentCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "negative-test-event-type");
        segmentCondition.setParameter("eventCondition", pastEventEventCondition);
        segmentCondition.setParameter("operator", "eventsNotOccurred");
        segment.setCondition(segmentCondition);
        segmentService.setSegmentDefinition(segment);

        // insure that profile is correctly engaged in sement since there is no events yet.
        keepTrying("Profile should be engaged in the segment, there is no event for the past condition yet",
                () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getSegments().contains("negative-past-event-segment-test"), 1000, 20);

        // we load the profile so that we are sure that it contains the segments
        profile = profileService.load("test_profile_id");

        // send event for profile from a previous date (today -3 days)
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        Event testEvent = new Event("negative-test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        int changes = eventService.send(testEvent);
        if ((changes & EventService.PROFILE_UPDATED) == EventService.PROFILE_UPDATED) {
            profileService.save(profile);
            persistenceService.refreshIndex(Profile.class, null);
        }
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // now Profile should be out of the segment since one event have been done and the past event is only valid for no events occurrences
        keepTrying("Profile should not be engaged in the segment anymore, it have a least one event now",
                () -> profileService.load("test_profile_id"),
                updatedProfile -> !updatedProfile.getSegments().contains("negative-past-event-segment-test"), 1000, 20);
    }

    @Test
    public void testSegmentPastEventRecalculation() throws Exception {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // create the segment
        Metadata segmentMetadata = new Metadata("past-event-segment-test");
        Segment segment = new Segment(segmentMetadata);
        Condition segmentCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        segmentCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        segmentCondition.setParameter("eventCondition", pastEventEventCondition);
        segment.setCondition(segmentCondition);
        segmentService.setSegmentDefinition(segment);
        Thread.sleep(5000);

        profile = profileService.load("test_profile_id");
        // Persist the event (do not send it into the system so that it will not be processed by the rules)
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        Event testEvent = new Event("test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        persistenceService.save(testEvent, null, true);
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // insure the profile is not yet engaged since we directly saved the event in ES
        profile = profileService.load("test_profile_id");
        Assert.assertFalse("Profile should not be engaged in the segment", profile.getSegments().contains("past-event-segment-test"));

        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should be engaged in the segment", () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getSegments().contains("past-event-segment-test"), 1000, 20);

        // update the event to a date out of the past event condition
        removeItems(Event.class);
        localDate = LocalDate.now().minusDays(15);
        testEvent = new Event("test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        persistenceService.save(testEvent);
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should not be engaged in the segment anymore", () -> profileService.load("test_profile_id"),
                updatedProfile -> !updatedProfile.getSegments().contains("past-event-segment-test"), 1000, 20);
    }

    @Test
    public void testScoringWithPastEventCondition() throws InterruptedException {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // send event for profile from a previous date (today -3 days)
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        Event testEvent = new Event("test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        int changes = eventService.send(testEvent);
        if ((changes & EventService.PROFILE_UPDATED) == EventService.PROFILE_UPDATED) {
            profileService.save(profile);
            persistenceService.refreshIndex(Profile.class, null);
        }
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // create the past event condition
        Condition pastEventCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        pastEventCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        pastEventCondition.setParameter("eventCondition", pastEventEventCondition);

        // create the scoring plan
        Metadata scoringMetadata = new Metadata("past-event-scoring-test");
        Scoring scoring = new Scoring(scoringMetadata);
        List<ScoringElement> scoringElements = new ArrayList<>();
        ScoringElement scoringElement = new ScoringElement();
        scoringElement.setCondition(pastEventCondition);
        scoringElement.setValue(50);
        scoringElements.add(scoringElement);
        scoring.setElements(scoringElements);
        segmentService.setScoringDefinition(scoring);

        // insure the profile that did the past event condition is correctly engaged in the scoring plan.
        keepTrying("Profile should be engaged in the scoring with a score of 50", () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getScores() != null && updatedProfile.getScores().containsKey("past-event-scoring-test")
                        && updatedProfile.getScores().get("past-event-scoring-test") == 50, 1000, 20);
    }

    @Test
    public void testScoringPastEventRecalculation() throws Exception {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // create the past event condition
        Condition pastEventCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        pastEventCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        pastEventCondition.setParameter("eventCondition", pastEventEventCondition);

        // create the scoring
        Metadata scoringMetadata = new Metadata("past-event-scoring-test");
        Scoring scoring = new Scoring(scoringMetadata);
        List<ScoringElement> scoringElements = new ArrayList<>();
        ScoringElement scoringElement = new ScoringElement();
        scoringElement.setCondition(pastEventCondition);
        scoringElement.setValue(50);
        scoringElements.add(scoringElement);
        scoring.setElements(scoringElements);
        segmentService.setScoringDefinition(scoring);
        Thread.sleep(5000);

        // Persist the event (do not send it into the system so that it will not be processed by the rules)
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        Event testEvent = new Event("test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        persistenceService.save(testEvent, null, true);
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // insure the profile is not yet engaged since we directly saved the event in ES
        profile = profileService.load("test_profile_id");
        Assert.assertTrue("Profile should not be engaged in the scoring",
                profile.getScores() == null || !profile.getScores().containsKey("past-event-scoring-test"));

        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should be engaged in the scoring with a score of 50", () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getScores() != null && updatedProfile.getScores().containsKey("past-event-scoring-test")
                        && updatedProfile.getScores().get("past-event-scoring-test") == 50, 1000, 20);

        // update the event to a date out of the past event condition
        removeItems(Event.class);
        localDate = LocalDate.now().minusDays(15);
        testEvent = new Event("test-event-type", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        persistenceService.save(testEvent);
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should not be engaged in the scoring anymore", () -> profileService.load("test_profile_id"),
                updatedProfile -> !updatedProfile.getScores().containsKey("past-event-scoring-test"), 1000, 20);
    }

    @Test
    public void testScoringPastEventRecalculationMaximumEventCount() throws Exception {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // create the past event condition
        Condition pastEventCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        pastEventCondition.setParameter("numberOfDays", 10);
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type-max");
        pastEventCondition.setParameter("eventCondition", pastEventEventCondition);
        pastEventCondition.setParameter("maximumEventCount", 1);

        // create the scoring
        Metadata scoringMetadata = new Metadata("past-event-scoring-test-max");
        Scoring scoring = new Scoring(scoringMetadata);
        List<ScoringElement> scoringElements = new ArrayList<>();
        ScoringElement scoringElement = new ScoringElement();
        scoringElement.setCondition(pastEventCondition);
        scoringElement.setValue(50);
        scoringElements.add(scoringElement);
        scoring.setElements(scoringElements);
        segmentService.setScoringDefinition(scoring);
        Thread.sleep(5000);

        // Persist the event (do not send it into the system so that it will not be processed by the rules)
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        Event testEvent = new Event("test-event-type-max", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        persistenceService.save(testEvent, null, true);
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // insure the profile is not yet engaged since we directly saved the event in ES
        profile = profileService.load("test_profile_id");
        Assert.assertTrue("Profile should not be engaged in the scoring",
                profile.getScores() == null || !profile.getScores().containsKey("past-event-scoring-test-max"));

        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should be engaged in the scoring with a score of 50", () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getScores() != null && updatedProfile.getScores()
                        .containsKey("past-event-scoring-test-max") && updatedProfile.getScores().get("past-event-scoring-test-max") == 50,
                1000, 20);

        // Persist the 2 event (do not send it into the system so that it will not be processed by the rules)
        defaultZoneId = ZoneId.systemDefault();
        localDate = LocalDate.now().minusDays(3);
        testEvent = new Event("test-event-type-max", null, profile, null, null, profile,
                Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        testEvent.setPersistent(true);
        persistenceService.save(testEvent, null, true);
        persistenceService.refreshIndex(Event.class, testEvent.getTimeStamp()); // wait for event to be fully persisted and indexed

        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should not be engaged in the scoring anymore", () -> profileService.load("test_profile_id"),
                updatedProfile -> !updatedProfile.getScores().containsKey("past-event-scoring-test-max"), 1000, 20);
    }

    @Test
    public void testScoringRecalculation() throws Exception {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        Date timestampEventInRange = new SimpleDateFormat("yyyy-MM-dd").parse("2000-10-30");
        // create the past event condition
        Condition pastEventCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        pastEventCondition.setParameter("minimumEventCount", 1);
        pastEventCondition.setParameter("maximumEventCount", 2);

        pastEventCondition.setParameter("fromDate", "2000-07-15T07:00:00Z");
        pastEventCondition.setParameter("toDate", "2001-01-15T07:00:00Z");
        ;
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        pastEventCondition.setParameter("eventCondition", pastEventEventCondition);

        // create the scoring
        Metadata scoringMetadata = new Metadata("past-event-scoring-test");
        Scoring scoring = new Scoring(scoringMetadata);
        List<ScoringElement> scoringElements = new ArrayList<>();
        ScoringElement scoringElement = new ScoringElement();
        scoringElement.setCondition(pastEventCondition);
        scoringElement.setValue(50);
        scoringElements.add(scoringElement);
        scoring.setElements(scoringElements);
        segmentService.setScoringDefinition(scoring);
        refreshPersistence();

        // Send 2 events that match the scoring plan.
        profile = profileService.load("test_profile_id");
        Event testEvent = new Event("test-event-type", null, profile, null, null, profile, timestampEventInRange);
        testEvent.setPersistent(true);
        eventService.send(testEvent);
        refreshPersistence();
        // 2nd event
        testEvent = new Event("test-event-type", null, testEvent.getProfile(), null, null, testEvent.getProfile(), timestampEventInRange);
        eventService.send(testEvent);
        refreshPersistence();

        // insure the profile is engaged;
        try {
            Assert.assertTrue("Profile should have 2 events in the scoring",
                    (Long) ((Map) testEvent.getProfile().getSystemProperties().get("pastEvents"))
                            .get(pastEventCondition.getParameterValues().get("generatedPropertyKey")) == 2);
            Assert.assertTrue("Profile is engaged", testEvent.getProfile().getScores().containsKey("past-event-scoring-test")
                    && testEvent.getProfile().getScores().get("past-event-scoring-test") == 50);
        } catch (Exception e) {
            Assert.fail("Unable to read past event because " + e.getMessage());
        }
        profileService.save(testEvent.getProfile());
        refreshPersistence();
        // recalculate event conditions
        segmentService.recalculatePastEventConditions();
        // insure the profile is still engaged after recalculate;
        keepTrying("Profile should have 2 events in the scoring", () -> profileService.load("test_profile_id"), updatedProfile -> {
            try {
                boolean eventCounted = (Integer) ((Map) updatedProfile.getSystemProperties().get("pastEvents"))
                        .get(pastEventCondition.getParameterValues().get("generatedPropertyKey")) == 2;
                boolean profileEngaged = updatedProfile.getScores().containsKey("past-event-scoring-test")
                        && updatedProfile.getScores().get("past-event-scoring-test") == 50;
                return eventCounted && profileEngaged;
            } catch (Exception e) {
                // Do nothing, unable to read value
            }
            ;
            return false;
        }, 1000, 20);

        // Add one more event
        testEvent = new Event("test-event-type", null, testEvent.getProfile(), null, null, testEvent.getProfile(), timestampEventInRange);
        eventService.send(testEvent);

        // As 3 events have match, the profile should not be part of the scoring plan.
        try {
            Assert.assertTrue("Profile should have no scoring", testEvent.getProfile().getScores().get("past-event-scoring-test") == 0);
        } catch (Exception e) {
            Assert.fail("Unable to read past event because " + e.getMessage());
        }
        profileService.save(testEvent.getProfile());
        refreshPersistence();
        // now recalculate the past event conditions
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        // As 3 events have match, the profile should not be part of the scoring plan.
        keepTrying("Profile should not be part of the scoring anymore", () -> profileService.load("test_profile_id"), updatedProfile -> {
            try {
                return updatedProfile.getScores().get("past-event-scoring-test") == 0;
            } catch (Exception e) {
                // Do nothing, unable to read value
            }
            ;
            return false;
        }, 1000, 20);
    }

    @Test
    public void testLinkedItems() throws Exception {

        // create the past event condition
        Condition pastEventCondition = new Condition(definitionsService.getConditionType("pastEventCondition"));
        pastEventCondition.setParameter("minimumEventCount", 1);
        pastEventCondition.setParameter("maximumEventCount", 2);

        pastEventCondition.setParameter("fromDate", "2000-07-15T07:00:00Z");
        pastEventCondition.setParameter("toDate", "2001-01-15T07:00:00Z");
        ;
        Condition pastEventEventCondition = new Condition(definitionsService.getConditionType("eventTypeCondition"));
        pastEventEventCondition.setParameter("eventTypeId", "test-event-type");
        pastEventCondition.setParameter("eventCondition", pastEventEventCondition);

        // create the scoring
        Metadata scoringMetadata = new Metadata("past-event-scoring-test");
        Scoring scoring = new Scoring(scoringMetadata);
        List<ScoringElement> scoringElements = new ArrayList<>();
        ScoringElement scoringElement = new ScoringElement();
        scoringElement.setCondition(pastEventCondition);
        scoringElement.setValue(50);
        scoringElements.add(scoringElement);
        scoring.setElements(scoringElements);
        segmentService.setScoringDefinition(scoring);
        refreshPersistence();
        // Check linkedItems
        List<Rule> rules = persistenceService.getAllItems(Rule.class);
        Rule scoringRule = rules.stream().filter(rule -> rule.getItemId().equals(pastEventCondition.getParameter("generatedPropertyKey")))
                .findFirst().get();
        Assert.assertEquals("Scoring linked Item should be one", 1, scoringRule.getLinkedItems().size());

        // save the scoring once again
        segmentService.setScoringDefinition(scoring);
        refreshPersistence();
        // Check linkedItems
        rules = persistenceService.getAllItems(Rule.class);
        scoringRule = rules.stream().filter(rule -> rule.getItemId().equals(pastEventCondition.getParameter("generatedPropertyKey")))
                .findFirst().get();
        Assert.assertEquals("Scoring linked Item should be one", 1, scoringRule.getLinkedItems().size());

        // Remove scoring
        segmentService.removeSegmentDefinition(scoring.getItemId(), true);
        refreshPersistence();
        // Check linkedItems
        rules = persistenceService.getAllItems(Rule.class);
        boolean isRule = rules.stream().anyMatch(rule -> rule.getItemId().equals(pastEventCondition.getParameter("generatedPropertyKey")));
        Assert.assertFalse("Rule is properly removed", isRule);
    }

    @Test
    public void testSegmentWithRelativeDateExpressions() throws Exception {
        // create Profile
        Profile profile = new Profile();
        profile.setItemId("test_profile_id");
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // create the conditions
        Condition booleanCondition = new Condition(definitionsService.getConditionType("booleanCondition"));
        List<Condition> subConditions = new ArrayList<>();
        Condition dateExpCondition = new Condition(definitionsService.getConditionType("profilePropertyCondition"));
        dateExpCondition.setParameter("propertyName", "properties.lastVisit");
        dateExpCondition.setParameter("comparisonOperator", "greaterThanOrEqualTo");
        dateExpCondition.setParameter("propertyValueDateExpr", "now-5d");
        subConditions.add(dateExpCondition);
        Condition otherCondition = new Condition(definitionsService.getConditionType("profilePropertyCondition"));
        otherCondition.setParameter("propertyName", "properties.address");
        otherCondition.setParameter("comparisonOperator", "notEquals");
        otherCondition.setParameter("propertyValueDateExpr", "test");
        subConditions.add(otherCondition);
        booleanCondition.setParameter("operator", "and");
        booleanCondition.setParameter("subConditions", subConditions);

        // create segment and scoring
        Metadata segmentMetadata = new Metadata("relative-date-segment-test");
        Segment segment = new Segment(segmentMetadata);
        segment.setCondition(booleanCondition);
        segmentService.setSegmentDefinition(segment);
        Metadata scoringMetadata = new Metadata("relative-date-scoring-test");
        Scoring scoring = new Scoring(scoringMetadata);
        ScoringElement scoringElement = new ScoringElement();
        scoringElement.setCondition(booleanCondition);
        scoringElement.setValue(5);
        scoring.setElements(Collections.singletonList(scoringElement));
        segmentService.setScoringDefinition(scoring);
        Thread.sleep(5000);

        // insure the profile is not yet engaged since we directly saved the profile in ES
        profile = profileService.load("test_profile_id");
        Assert.assertFalse("Profile should not be engaged in the segment", profile.getSegments().contains("relative-date-segment-test"));
        Assert.assertTrue("Profile should not be engaged in the scoring",
                profile.getScores() == null || !profile.getScores().containsKey("relative-date-scoring-test"));

        // Update the profile last visit to match the segment ans the scoring
        ZoneId defaultZoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now().minusDays(3);
        profile.setProperty("lastVisit", Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // insure the profile is not yet engaged since we directly saved the profile in ES
        profile = profileService.load("test_profile_id");
        Assert.assertFalse("Profile should not be engaged in the segment", profile.getSegments().contains("relative-date-segment-test"));
        Assert.assertTrue("Profile should not be engaged in the scoring",
                profile.getScores() == null || profile.getScores().containsKey("relative-date-scoring-test"));

        // now force the recalculation of the date relative segments/scorings
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should be engaged in the segment and scoring", () -> profileService.load("test_profile_id"),
                updatedProfile -> updatedProfile.getSegments().contains("relative-date-segment-test") && updatedProfile.getScores() != null
                        && updatedProfile.getScores().get("relative-date-scoring-test") == 5, 1000, 20);

        // update the profile to a date out of date expression
        localDate = LocalDate.now().minusDays(15);
        profile.setProperty("lastVisit", Date.from(localDate.atStartOfDay(defaultZoneId).toInstant()));
        profileService.save(profile);
        persistenceService.refreshIndex(Profile.class, null); // wait for profile to be full persisted and index

        // now force the recalculation of the date relative segments/scorings
        segmentService.recalculatePastEventConditions();
        persistenceService.refreshIndex(Profile.class, null);
        keepTrying("Profile should not be engaged in the segment and scoring anymore", () -> profileService.load("test_profile_id"),
                updatedProfile -> !updatedProfile.getSegments().contains("relative-date-segment-test") && (
                        updatedProfile.getScores() == null || !updatedProfile.getScores().containsKey("relative-date-scoring-test")), 1000,
                20);
    }
}
