package ru.yandex.autotests.directapi.reports;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.yandex.direct.api.v5.general.SortOrderEnum;
import com.yandex.direct.api.v5.reports.DateRangeTypeEnum;
import com.yandex.direct.api.v5.reports.FieldEnum;
import com.yandex.direct.api.v5.reports.FilterOperatorEnum;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;

import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.apiclient.errors.Api5Error;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetails;
import ru.yandex.autotests.directapi.darkside.Logins;
import ru.yandex.autotests.directapi.model.api5.reports.FilterItemMap;
import ru.yandex.autotests.directapi.model.api5.reports.FilterValueEnum;
import ru.yandex.autotests.directapi.model.api5.reports.OrderByMap;
import ru.yandex.autotests.directapi.model.api5.reports.PageMap;
import ru.yandex.autotests.directapi.model.api5.reports.ReportDefinitionMap;
import ru.yandex.autotests.directapi.model.api5.reports.ReportsData;
import ru.yandex.autotests.directapi.model.api5.reports.ReportsLine;
import ru.yandex.autotests.directapi.model.api5.reports.SelectionCriteriaMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.irt.testutils.matchers.OrderMatcher;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Issue;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.direct.utils.matchers.BeanEqualsAssert.assertThat;
import static ru.yandex.autotests.directapi.matchers.beans.version5.BeanDifferMatcherV5.beanEquivalentV5;

/**
 * Created by onotole on 08.12.16.
 * https://st.yandex-team.ru/DIRECT-58959 
 */

@Aqua.Test
@Description("Проверка среза по корректировке условия подбора")
@Issue("https://st.yandex-team.ru/TESTIRT-10477")
@Features(ReportsFeatures.ONLINE_CUSTOM_REPORT)
public class AdjustmentReportTest {
    private static final String CLIENT = ReportsLogins.CLIENT_FOR_RL_ADJ_TEST;
    private static final int CAMPAIGN_ID = 20725925;
    private static final String DATE_FROM = "2021-04-01";
    private static final String DATE_TO = "2021-04-03";
    private static final int RL_ADJUSTMENT_ID = 2093477;
    private static ArrayList<ReportsLine> expectedReport;
    private static ArrayList<ReportsLine> expectedReportRlAdj;

    @ClassRule
    public static ApiSteps api = new ApiSteps().as(Logins.LOGIN_SUPER).clientLogin(CLIENT);

    @ClassRule
    public static SemaphoreRule semaphore = Semaphore.getSemaphore();

    @BeforeClass
    public static void prepareData() {
        // for first test
        expectedReport = new ArrayList<>();
        ReportsLine rl = new ReportsLine();
        rl.setClicks(27);
        expectedReport.add(rl);

        rl = new ReportsLine();
        rl.setRlAdjustmentId(RL_ADJUSTMENT_ID);
        rl.setClicks(10);
        expectedReport.add(rl);

        // for second test
        expectedReportRlAdj = new ArrayList<>();
        rl = new ReportsLine();
        rl.setClicks(2);
        rl.setRlAdjustmentId(RL_ADJUSTMENT_ID);
        rl.setCriteria("Свадебное платье крым");
        expectedReportRlAdj.add(rl);

        rl = new ReportsLine();
        rl.setClicks(2);
        rl.setRlAdjustmentId(RL_ADJUSTMENT_ID);
        rl.setCriteria("свадебный салон симферополь -скидка");
        expectedReportRlAdj.add(rl);
    }

    @Test
    public void checkAdjustmentIdTest() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withSelectionCriteria(
                        new SelectionCriteriaMap().withFilter(
                                new FilterItemMap()
                                    .withField(FieldEnum.CAMPAIGN_ID)
                                    .withOperator(FilterOperatorEnum.EQUALS)
                                    .withValues(CAMPAIGN_ID),
                                new FilterItemMap()
                                        .withField(FieldEnum.CLICKS)
                                        .withOperator(FilterOperatorEnum.GREATER_THAN)
                                        .withValues(0)
                        )
                                .withDateTo(DATE_TO)
                                .withDateFrom(DATE_FROM)
                ).withPage(new PageMap().withLimit(1000L))
                .withDateRangeType(DateRangeTypeEnum.CUSTOM_DATE)
                .withOrderBy(new OrderByMap().withField(FieldEnum.RL_ADJUSTMENT_ID))
                .withFieldNames(FieldEnum.CLICKS, FieldEnum.RL_ADJUSTMENT_ID);
        ReportsData reportsData = api.userSteps.reportsSteps().callReportsXml(reportDefinitionMap);

        assertThat("полученный отчет совпал с ожидаемым", reportsData.getReportsLines(), beanEquivalentV5(expectedReport));
    }

    @Test
    public void checkAdjustmentIdCriteriaTest() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withSelectionCriteria(
                        new SelectionCriteriaMap().withFilter(
                                new FilterItemMap()
                                        .withField(FieldEnum.CAMPAIGN_ID)
                                        .withOperator(FilterOperatorEnum.EQUALS)
                                        .withValues(CAMPAIGN_ID),
                                new FilterItemMap()
                                        .withField(FieldEnum.CLICKS)
                                        .withOperator(FilterOperatorEnum.GREATER_THAN)
                                        .withValues(1),
                                new FilterItemMap()
                                        .withField(FieldEnum.RL_ADJUSTMENT_ID)
                                        .withOperator(FilterOperatorEnum.EQUALS)
                                        .withValues(RL_ADJUSTMENT_ID)
                        )
                                .withDateTo(DATE_TO)
                                .withDateFrom(DATE_FROM)
                ).withPage(new PageMap().withLimit(1000L))
                .withDateRangeType(DateRangeTypeEnum.CUSTOM_DATE)
                .withOrderBy(new OrderByMap().withField(FieldEnum.RL_ADJUSTMENT_ID),
                        new OrderByMap().withField(FieldEnum.IMPRESSIONS))
                .withFieldNames(FieldEnum.IMPRESSIONS, FieldEnum.CLICKS, FieldEnum.RL_ADJUSTMENT_ID, FieldEnum.CRITERIA);
        ReportsData reportsData = api.userSteps.reportsSteps().callReportsXml(reportDefinitionMap);

        assertThat("полученный отчет совпал с ожидаемым", reportsData.getReportsLines(), beanEquivalentV5(expectedReportRlAdj));
    }

    @Test
    public void checkOrderByAdjustmentIdTest() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withSelectionCriteria(
                        new SelectionCriteriaMap().withFilter(
                                new FilterItemMap()
                                        .withField(FieldEnum.RL_ADJUSTMENT_ID)
                                        .withOperator(FilterOperatorEnum.NOT_EQUALS)
                                        .withValues(FilterValueEnum.NONE.value())
                        )
                                .withDateTo(DATE_TO)
                                .withDateFrom(DATE_FROM)
                )
                .withDateRangeType(DateRangeTypeEnum.CUSTOM_DATE)
                .withFieldNames(FieldEnum.RL_ADJUSTMENT_ID)
                .withPage(new PageMap().withLimit(1000L))
                .withOrderBy(new OrderByMap()
                    .withField(FieldEnum.RL_ADJUSTMENT_ID)
                    .withSortOrder(SortOrderEnum.DESCENDING));
        ReportsData reportsData = api.userSteps.reportsSteps().callReportsXml(reportDefinitionMap);
        List<Integer> rlAdjIds = reportsData.getReportsLines().stream().map(ReportsLine::getRlAdjustmentId).collect(Collectors.toList());
        assertThat("rlAdjId вернулись в верном порядке", rlAdjIds, OrderMatcher.isDescendingOrdered());
    }

    @Test
    public void negativeFilterByRlAdjIdTest() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withSelectionCriteria(
                        new SelectionCriteriaMap()
                            .withFilter(new FilterItemMap()
                                .withField(FieldEnum.RL_ADJUSTMENT_ID)
                                .withOperator(FilterOperatorEnum.EQUALS)
                                .withValues("blah"))
                )
                .withDateRangeType(DateRangeTypeEnum.TODAY)
                .withFieldNames(FieldEnum.RL_ADJUSTMENT_ID)
                .withPage(new PageMap().withLimit(1000L));

        api.userSteps.reportsSteps().expectXmlErrorOnReports(reportDefinitionMap,
                new Api5Error(4001, Api5ErrorDetails.INCORRECT_IDENTIFICATOR_FOR_FILTER, FieldEnum.RL_ADJUSTMENT_ID.value()));

    }

}
