<commit_before>/*
 * Copyright (C) 2018 EPAM Systems
 *
 * Licensed 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 com.epam.ta.reportportal.util.integration.email;

import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
import com.epam.ta.reportportal.entity.integration.Integration;
import com.epam.ta.reportportal.entity.integration.IntegrationParams;
import com.epam.ta.reportportal.entity.integration.IntegrationType;
import com.epam.ta.reportportal.entity.project.Project;
import com.epam.ta.reportportal.entity.project.ProjectUtils;
import com.epam.ta.reportportal.entity.project.email.LaunchStatsRule;
import com.epam.ta.reportportal.entity.project.email.SendCaseType;
import com.epam.ta.reportportal.entity.user.ProjectUser;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.util.integration.IntegrationService;
import com.epam.ta.reportportal.ws.model.ErrorType;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.epam.ta.reportportal.commons.Preconditions.NOT_EMPTY_COLLECTION;
import static com.epam.ta.reportportal.commons.Predicates.equalTo;
import static com.epam.ta.reportportal.commons.Predicates.notNull;
import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
import static com.epam.ta.reportportal.dao.constant.WidgetRepositoryConstants.OWNER;
import static com.epam.ta.reportportal.entity.project.ProjectUtils.getOwner;
import static com.epam.ta.reportportal.entity.project.email.SendCaseType.*;
import static com.epam.ta.reportportal.util.UserUtils.isEmailValid;
import static com.epam.ta.reportportal.util.integration.email.EmailIntegrationUtil.*;
import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
import static com.epam.ta.reportportal.ws.model.ErrorType.USER_NOT_FOUND;
import static com.epam.ta.reportportal.ws.model.ValidationConstraints.*;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;

/**
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
@Component
public class EmailIntegrationService implements IntegrationService {

	@Autowired
	private IntegrationTypeRepository integrationTypeRepository;

	@Override
	public boolean validateIntegrationParameters(Project project, Map<String, Object> integrationParameters) {
		expect(integrationParameters, notNull()).verify(BAD_REQUEST_ERROR, "Integration parameters should be provided.");
		List<Map<String, Object>> rules = getEmailRules(integrationParameters);
		expect(rules, NOT_EMPTY_COLLECTION).verify(BAD_REQUEST_ERROR, "At least one rule should be present.");
		rules.forEach(rule -> {
			String sendCase = getLaunchStatsValue(rule);
			expect(LaunchStatsRule.findByName(sendCase).isPresent(), equalTo(true)).verify(BAD_REQUEST_ERROR, sendCase);

			validateRecipients(project, getRuleValues(rule, RECIPIENTS));
			validateLaunchName(getRuleValues(rule, LAUNCH_NAME_RULE));
			rule.put(LAUNCH_TAG_RULE.getCaseTypeString(), validateTags(getRuleValues(rule, LAUNCH_TAG_RULE)));
		});

		return true;
	}

	/**
	 * Setup default project email configuration
	 *
	 * @param project Project
	 * @return project object with default email config
	 */
	public Project setDefaultEmailConfiguration(Project project) {
		Optional<IntegrationType> email = integrationTypeRepository.findByNameAndIntegrationGroup(EMAIL, IntegrationGroupEnum.NOTIFICATION);
		expect(email, Optional::isPresent).verify(ErrorType.INTEGRATION_NOT_FOUND, EMAIL);

		Map<String, Object> defaultCases = new HashMap<>();
		defaultCases.put(RECIPIENTS.getCaseTypeString(), Lists.newArrayList(OWNER));
		defaultCases.put(SendCaseType.LAUNCH_STATS_RULE.getCaseTypeString(), Lists.newArrayList(LaunchStatsRule.ALWAYS.getRuleString()));
		IntegrationParams integrationParams = new IntegrationParams(defaultCases);

		Integration integration = new Integration();
		integration.setParams(integrationParams);
		integration.setProject(project);
		integration.setType(email.get());

		project.getIntegrations().add(integration);
		return project;
	}

	/**
	 * Exclude specified project users
	 *
	 * @param projectUsers Users
	 * @param project      Project
	 */
	public void excludeProjectRecipients(Iterable<ProjectUser> projectUsers, Project project) {
		if (projectUsers != null) {
			List<String> toExclude = stream(projectUsers.spliterator(), false).map(projectUser -> asList(projectUser.getUser()
					.getEmail()<commit_msg>replace launch stats rule with option<commit_after>/*
 * Copyright (C) 2018 EPAM Systems
 *
 * Licensed 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 com.epam.ta.reportportal.util.integration.email;

import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
import com.epam.ta.reportportal.entity.integration.Integration;
import com.epam.ta.reportportal.entity.integration.IntegrationParams;
import com.epam.ta.reportportal.entity.integration.IntegrationType;
import com.epam.ta.reportportal.entity.project.Project;
import com.epam.ta.reportportal.entity.project.ProjectUtils;
import com.epam.ta.reportportal.entity.project.email.LaunchStatsRule;
import com.epam.ta.reportportal.entity.project.email.SendCaseType;
import com.epam.ta.reportportal.entity.user.ProjectUser;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.util.integration.IntegrationService;
import com.epam.ta.reportportal.ws.model.ErrorType;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.epam.ta.reportportal.commons.Preconditions.NOT_EMPTY_COLLECTION;
import static com.epam.ta.reportportal.commons.Predicates.equalTo;
import static com.epam.ta.reportportal.commons.Predicates.notNull;
import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
import static com.epam.ta.reportportal.dao.constant.WidgetRepositoryConstants.OWNER;
import static com.epam.ta.reportportal.entity.project.ProjectUtils.getOwner;
import static com.epam.ta.reportportal.entity.project.email.SendCaseType.*;
import static com.epam.ta.reportportal.util.UserUtils.isEmailValid;
import static com.epam.ta.reportportal.util.integration.email.EmailIntegrationUtil.*;
import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
import static com.epam.ta.reportportal.ws.model.ErrorType.USER_NOT_FOUND;
import static com.epam.ta.reportportal.ws.model.ValidationConstraints.*;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;

/**
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
@Component
public class EmailIntegrationService implements IntegrationService {

	@Autowired
	private IntegrationTypeRepository integrationTypeRepository;

	@Override
	public boolean validateIntegrationParameters(Project project, Map<String, Object> integrationParameters) {
		expect(integrationParameters, notNull()).verify(BAD_REQUEST_ERROR, "Integration parameters should be provided.");
		List<Map<String, Object>> rules = getEmailRules(integrationParameters);
		expect(rules, NOT_EMPTY_COLLECTION).verify(BAD_REQUEST_ERROR, "At least one rule should be present.");
		rules.forEach(rule -> {
			String sendCase = getLaunchStatsValue(rule);
			expect(LaunchStatsRule.findByName(sendCase).isPresent(), equalTo(true)).verify(BAD_REQUEST_ERROR, sendCase);

			validateRecipients(project, getRuleValues(rule, RECIPIENTS));
			validateLaunchName(getRuleValues(rule, LAUNCH_NAME_RULE));
			rule.put(LAUNCH_TAG_RULE.getCaseTypeString(), validateTags(getRuleValues(rule, LAUNCH_TAG_RULE)));
		});

		return true;
	}

	/**
	 * Setup default project email configuration
	 *
	 * @param project Project
	 * @return project object with default email config
	 */
	public Project setDefaultEmailConfiguration(Project project) {
		Optional<IntegrationType> email = integrationTypeRepository.findByNameAndIntegrationGroup(EMAIL, IntegrationGroupEnum.NOTIFICATION);
		expect(email, Optional::isPresent).verify(ErrorType.INTEGRATION_NOT_FOUND, EMAIL);

		Map<String, Object> defaultCases = new HashMap<>();
		defaultCases.put(RECIPIENTS.getCaseTypeString(), Lists.newArrayList(OWNER));
		defaultCases.put(SendCaseType.LAUNCH_STATS_RULE.getCaseTypeString(), LaunchStatsRule.ALWAYS.getRuleString());
		IntegrationParams integrationParams = new IntegrationParams(defaultCases);

		Integration integration = new Integration();
		integration.setParams(integrationParams);
		integration.setProject(project);
		integration.setType(email.get());

		project.getIntegrations().add(integration);
		return project;
	}

	/**
	 * Exclude specified project users
	 *
	 * @param projectUsers Users
	 * @param project      Project
	 */
	public void excludeProjectRecipients(Iterable<ProjectUser> projectUsers, Project project) {
		if (projectUsers != null) {
			List<String> toExclude = stream(projectUsers.spliterator(), false).map(projectUser -> asList(projectUser.getUser()
					.getEmail()
{'fraction_non_alphanumeric': 0.10344511636430273, 'fraction_numerical': 0.0014660069635330768, 'mean_word_length': 6.223692918596956, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1923611', 'n_tokens_mistral': 3253, 'n_tokens_neox': 3163, 'n_words': 626}