package ru.yandex.autotests.directapi.reports;

import com.yandex.direct.api.v5.general.YesNoEnum;
import com.yandex.direct.api.v5.reports.DateRangeTypeEnum;
import com.yandex.direct.api.v5.reports.FieldEnum;
import com.yandex.direct.api.v5.reports.FormatEnum;
import com.yandex.direct.api.v5.reports.ReportTypeEnum;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.directapi.darkside.Logins;
import ru.yandex.autotests.directapi.darkside.connection.Semaphore;
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.SelectionCriteriaMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
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 org.hamcrest.Matchers.equalTo;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by onotole on 7/28/16.
 * https://st.yandex-team.ru/TESTIRT-9906
 */
@Aqua.Test
@Description("Проверка работы группировок, группировка по нескольки полям")
@Issue("https://st.yandex-team.ru/TESTIRT-9244")
@Features(ReportsFeatures.ONLINE_CUSTOM_REPORT)
public class GroupByManyFieldsTest {
    private static final String CLIENT = ReportsLogins.CLIENT_RUB_WITH_STAT2;
    private static final String dateFrom = "2020-06-02";
    private static final String dateTo = "2020-08-02";
    private static final int COUNT_OF_ROWS_IN_SOME_FIELDS_REPORT = 28;
    private static final int COUNT_OF_ROWS_IN_MANY_FIELDS_REPORT = 1258;
    private static ReportsData groupedByManyFieldsReportsData;
    private static ReportsData reportsData;

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

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

    @BeforeClass
    public static void callReports() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withFieldNames(FieldEnum.CLICKS, FieldEnum.IMPRESSIONS, FieldEnum.REVENUE, FieldEnum.AGE,
                        FieldEnum.AD_NETWORK_TYPE, FieldEnum.CARRIER_TYPE)
                .withDateRangeType(DateRangeTypeEnum.CUSTOM_DATE)
                .withUniqueReportName()
                .withReportType(ReportTypeEnum.CUSTOM_REPORT)
                .withFormat(FormatEnum.TSV)
                .withIncludeVAT(YesNoEnum.YES)
                .withIncludeDiscount(YesNoEnum.NO)
                .withSelectionCriteria(new SelectionCriteriaMap()
                        .withDateFrom(dateFrom)
                        .withDateTo(dateTo));
        reportsData = api.userSteps.reportsSteps().callReportsXml(reportDefinitionMap);
        assumeThat("вернулся репорт с ожидаемым количеством строк", reportsData.getReportsLines().size(), equalTo(COUNT_OF_ROWS_IN_SOME_FIELDS_REPORT));

        ReportDefinitionMap groupedByManyFieldReportsDefinitionMap = new ReportDefinitionMap()
                .withFieldNames(FieldEnum.CLICKS, FieldEnum.IMPRESSIONS, FieldEnum.REVENUE, FieldEnum.AGE,
                        FieldEnum.AD_NETWORK_TYPE, FieldEnum.CARRIER_TYPE, FieldEnum.CRITERIA_TYPE,
                        FieldEnum.DEVICE, FieldEnum.GENDER, FieldEnum.AD_FORMAT, FieldEnum.MOBILE_PLATFORM, FieldEnum.SLOT)
                .withDateRangeType(DateRangeTypeEnum.CUSTOM_DATE)
                .withUniqueReportName()
                .withReportType(ReportTypeEnum.CUSTOM_REPORT)
                .withFormat(FormatEnum.TSV)
                .withIncludeVAT(YesNoEnum.YES)
                .withIncludeDiscount(YesNoEnum.NO)
                .withSelectionCriteria(new SelectionCriteriaMap()
                        .withDateFrom(dateFrom)
                        .withDateTo(dateTo));
        groupedByManyFieldsReportsData = api.userSteps.reportsSteps().callReportsXml(groupedByManyFieldReportsDefinitionMap);
        assumeThat("вернулся репорт с ожидаемым количеством строк", groupedByManyFieldsReportsData.getReportsLines().size(), equalTo(COUNT_OF_ROWS_IN_MANY_FIELDS_REPORT));
    }


    @Test
    public void checkCommonClicksTest() {
        Integer clicksOfReport =
                reportsData.getReportsLines().stream()
                        .mapToInt(line -> line.getClicks())
                        .sum();
        Integer clicksOfGroupedByManyFiledsReport =
                groupedByManyFieldsReportsData.getReportsLines().stream()
                        .mapToInt(line -> line.getClicks())
                        .sum();
        assertThat("При группировке по большому количеству полей значения кликов не потерялись",
                clicksOfReport, equalTo(clicksOfGroupedByManyFiledsReport));

    }

    @Test
    public void checkCommonImpressionsTest() {
        Integer impressionsOfReport =
                reportsData.getReportsLines().stream()
                        .mapToInt(line -> line.getImpressions())
                        .sum();
        Integer impressionsOfGroupedByManyFiledsReport =
                groupedByManyFieldsReportsData.getReportsLines().stream()
                        .mapToInt(line -> line.getImpressions())
                        .sum();
        assertThat("При группировке по большому количеству полей значения показов не потерялись",
                impressionsOfReport, equalTo(impressionsOfGroupedByManyFiledsReport));
    }

    @Test
    public void checkCommonRevenueTest() {
        Long revenueOfReport =
                reportsData.getReportsLines().stream()
                        .mapToLong(line -> line.getRevenue().longValue())
                        .sum();
        Long revenueOfGroupedByManyFiledsReport =
                groupedByManyFieldsReportsData.getReportsLines().stream()
                        .mapToLong(line -> line.getRevenue().longValue())
                        .sum();
        assertThat("При группировке по большому количеству полей значения дохода не потерялись",
                revenueOfReport, equalTo(revenueOfGroupedByManyFiledsReport));
    }

}
