/*
 * 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.*;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.api.conditions.ConditionType;
import org.apache.unomi.api.rules.Rule;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.RulesService;
import org.apache.unomi.persistence.spi.CustomObjectMapper;
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.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.*;

import static org.junit.Assert.*;

/**
 * Integration tests for the Unomi rule service.
 */
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerSuite.class)
public class RuleServiceIT extends BaseIT {

    private final static Logger LOGGER = LoggerFactory.getLogger(RuleServiceIT.class);

    private final static String TEST_RULE_ID = "test-rule-id";
    public static final String TEST_SCOPE = "test-scope";

    @Before
    public void setUp() {
        TestUtils.removeAllProfiles(definitionsService, persistenceService);
    }

    @Test
    public void testRuleWithNullActions() throws InterruptedException {
        Metadata metadata = new Metadata(TEST_RULE_ID);
        metadata.setName(TEST_RULE_ID + "_name");
        metadata.setDescription(TEST_RULE_ID + "_description");
        metadata.setScope(TEST_SCOPE);
        Rule nullRule = new Rule(metadata);
        nullRule.setCondition(null);
        nullRule.setActions(null);
        createAndWaitForRule(nullRule);
        assertNull("Expected rule actions to be null", nullRule.getActions());
        assertNull("Expected rule condition to be null", nullRule.getCondition());
        assertEquals("Invalid rule name", TEST_RULE_ID + "_name", nullRule.getMetadata().getName());
        rulesService.removeRule(TEST_RULE_ID);
        refreshPersistence();
        rulesService.refreshRules();
    }

    @Test
    public void testRuleEventTypeOptimization() throws InterruptedException {

        ConditionBuilder builder = new ConditionBuilder(definitionsService);
        Rule simpleEventTypeRule = new Rule(new Metadata(TEST_SCOPE, "simple-event-type-rule", "Simple event type rule", "A rule with a simple condition to match an event type"));
        simpleEventTypeRule.setCondition(builder.condition("eventTypeCondition").parameter("eventTypeId", "view").build());
        createAndWaitForRule(simpleEventTypeRule);
        Rule complexEventTypeRule = new Rule(new Metadata(TEST_SCOPE, "complex-event-type-rule", "Complex event type rule", "A rule with a complex condition to match multiple event types with negations"));
        complexEventTypeRule.setCondition(
                builder.not(
                        builder.or(
                                builder.condition("eventTypeCondition").parameter( "eventTypeId", "view"),
                                builder.condition("eventTypeCondition").parameter("eventTypeId", "form")
                        )
                ).build()
        );
        createAndWaitForRule(complexEventTypeRule);
        Rule noEventTypeRule = new Rule(new Metadata(TEST_SCOPE, "no-event-type-rule", "No event type rule", "A rule with a simple condition but no event type matching"));
        noEventTypeRule.setCondition(builder.condition("eventPropertyCondition")
                .parameter("propertyName", "target.properties.pageInfo.language")
                .parameter("comparisonOperator", "equals")
                .parameter("propertyValue", "en")
                .build());
        createAndWaitForRule(noEventTypeRule);

        Profile profile = new Profile(UUID.randomUUID().toString());
        Session session = new Session(UUID.randomUUID().toString(), profile, new Date(), TEST_SCOPE);
        Event viewEvent = generateViewEvent(session, profile);
        Set<Rule> matchingRules = rulesService.getMatchingRules(viewEvent);

        assertTrue("Simple rule should be matched", matchingRules.contains(simpleEventTypeRule));
        assertFalse("Complex rule should NOT be matched", matchingRules.contains(complexEventTypeRule));
        assertTrue("No event type rule should be matched", matchingRules.contains(noEventTypeRule));

        Event loginEvent = new Event(UUID.randomUUID().toString(), "login", session, profile, TEST_SCOPE, null, null, new Date());
        matchingRules = rulesService.getMatchingRules(loginEvent);
        assertTrue("Complex rule should be matched", matchingRules.contains(complexEventTypeRule));
        assertFalse("Simple rule should NOT be matched", matchingRules.contains(simpleEventTypeRule));

        rulesService.removeRule(simpleEventTypeRule.getItemId());
        rulesService.removeRule(complexEventTypeRule.getItemId());
        rulesService.removeRule(noEventTypeRule.getItemId());
        refreshPersistence();
        rulesService.refreshRules();
    }

    @Test
    public void testRuleOptimizationPerf() throws NoSuchFieldException, IllegalAccessException, IOException, InterruptedException {
        Profile profile = new Profile(UUID.randomUUID().toString());
        Session session = new Session(UUID.randomUUID().toString(), profile, new Date(), TEST_SCOPE);

        updateConfiguration(RulesService.class.getName(), "org.apache.unomi.services", "rules.optimizationActivated", "false");
        rulesService = getService(RulesService.class);
        eventService = getService(EventService.class);

        LOGGER.info("Running unoptimized rules performance test...");
        long unoptimizedRunTime = runEventTest(profile, session);

        updateConfiguration(RulesService.class.getName(), "org.apache.unomi.services", "rules.optimizationActivated", "true");
        rulesService = getService(RulesService.class);
        eventService = getService(EventService.class);

        LOGGER.info("Running optimized rules performance test...");
        long optimizedRunTime = runEventTest(profile, session);

        double improvementRatio = ((double) unoptimizedRunTime) / ((double) optimizedRunTime);
        LOGGER.info("Unoptimized run time = {}ms, optimized run time = {}ms. Improvement={}x", unoptimizedRunTime, optimizedRunTime, improvementRatio);
        // we check with a ratio of 0.9 because the test can sometimes fail due to the fact that the sample size is small and can be affected by
        // environmental issues such as CPU or I/O load.
        assertTrue("Optimized run time should be smaller than unoptimized", improvementRatio > 0.9);
    }

    private long runEventTest(Profile profile, Session session) {
        LOGGER.info("eventService={}", eventService);
        Event viewEvent = generateViewEvent(session, profile);
        int loopCount = 0;
        long startTime = System.currentTimeMillis();
        while (loopCount < 500) {
            eventService.send(viewEvent);
            viewEvent = generateViewEvent(session, profile);
            loopCount++;
        }
        return System.currentTimeMillis() - startTime;
    }

    private Event generateViewEvent(Session session, Profile profile) {
        CustomItem sourceItem = new CustomItem();
        sourceItem.setScope(TEST_SCOPE);

        CustomItem targetItem = new CustomItem();
        targetItem.setScope(TEST_SCOPE);
        Map<String,Object> targetProperties = new HashMap<>();

        Map<String,Object> pageInfo = new HashMap<>();
        pageInfo.put("language", "en");
        pageInfo.put("destinationURL", "https://www.acme.com/test-page.html");
        pageInfo.put("referringURL", "https://unomi.apache.org");
        pageInfo.put("pageID", "ITEM_ID_PAGE");
        pageInfo.put("pagePath", "/test-page.html");
        pageInfo.put("pageName", "Test page");

        targetProperties.put("pageInfo", pageInfo);

        targetItem.setProperties(targetProperties);
        return new Event(UUID.randomUUID().toString(), "view", session, profile, TEST_SCOPE, sourceItem, targetItem, new Date());
    }

    @Test
    public void testGetTrackedConditions() throws InterruptedException, IOException {
        // Add custom condition with parameter
        try {
            ConditionType conditionType = CustomObjectMapper.getObjectMapper().readValue(
                    new File("data/tmp/testClickEventCondition.json").toURI().toURL(), ConditionType.class);
            definitionsService.setConditionType(conditionType);
            refreshPersistence();
            rulesService.refreshRules();
            // Test tracked parameter
            // Add rule that has a trackParameter condition that matches
            ConditionBuilder builder = new ConditionBuilder(definitionsService);
            Rule trackParameterRule = new Rule(new Metadata(TEST_SCOPE, "tracked-parameter-rule", "Tracked parameter rule", "A rule with tracked parameter"));
            Condition trackedCondition = builder.condition("clickEventCondition").build();
            trackedCondition.setParameter("path", "/test-page.html");
            trackedCondition.setParameter("referrer", "https://unomi.apache.org");
            trackedCondition.getConditionType().getMetadata().getSystemTags().add("trackedCondition");
            trackParameterRule.setCondition(trackedCondition);
            createAndWaitForRule(trackParameterRule);
            // Add rule that has a trackParameter condition that does not match
            Rule unTrackParameterRule = new Rule(new Metadata(TEST_SCOPE, "not-tracked-parameter-rule", "Not Tracked parameter rule", "A rule that has a parameter not tracked"));
            Condition unTrackedCondition = builder.condition("clickEventCondition").build();
            unTrackedCondition.setParameter("path", "/test-page.html");
            unTrackedCondition.setParameter("referrer", "https://localhost");
            unTrackedCondition.getConditionType().getMetadata().getSystemTags().add("trackedCondition");
            unTrackParameterRule.setCondition(unTrackedCondition);
            createAndWaitForRule(unTrackParameterRule);
            // Check that the given event return the tracked condition
            Profile profile = new Profile(UUID.randomUUID().toString());
            Session session = new Session(UUID.randomUUID().toString(), profile, new Date(), TEST_SCOPE);
            Event viewEvent = generateViewEvent(session, profile);
            Set<Condition> trackedConditions = rulesService.getTrackedConditions(viewEvent.getTarget());
            Assert.assertTrue(trackedConditions.contains(trackedCondition));
            Assert.assertFalse(trackedConditions.contains(unTrackedCondition));
        } finally {
            // Clean up test data
            rulesService.removeRule("tracked-parameter-rule");
            rulesService.removeRule("not-tracked-parameter-rule");
            definitionsService.removeConditionType("clickEventCondition");
        }
    }

    @Override
    public void updateServices() throws InterruptedException {
        super.updateServices();
        rulesService = getService(RulesService.class);
        eventService = getService(EventService.class);
    }
}
