package ru.yandex.autotests.directapi.reports.criteriareport;

import com.yandex.direct.api.v5.reports.FieldEnum;
import com.yandex.direct.api.v5.reports.ReportTypeEnum;
import org.joda.time.DateTime;
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.model.Logins;
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.reports.ReportsFeatures;
import ru.yandex.autotests.directapi.reports.ReportsLogins;
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.apache.commons.lang3.StringUtils.capitalize;
import static org.hamcrest.Matchers.*;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;
import static ru.yandex.autotests.irt.testutils.beandiffer2.BeanDifferMatcher.beanDiffer;

/**
 * Created by andy-ilyin on 13.01.17.
 */
@Aqua.Test
@Description("проверка скользящего окна дат в CRITERIA_PERFORMANCE_REPORT")
@Issue("https://st.yandex-team.ru/TESTIRT-10893")
@Features(ReportsFeatures.CRITERIA_PERFORMANCE_REPORT)
public class CriteriaPerformanceReportDateWindowTest {
    private static final Integer CURRENT_MONTH = DateTime.now().getMonthOfYear();
    private static final Integer CURRENT_YEAR = DateTime.now().getYear();
    private static final DateTime VALID_BOUNDARY_DAY = DateTime.now().withDate(CURRENT_YEAR - 3, CURRENT_MONTH, 1);
    private static final DateTime INVALID_BOUNDARY_DAY = VALID_BOUNDARY_DAY.minusDays(1);

    @ClassRule
    public static ApiSteps api = new ApiSteps().as(Logins.SUPER_LOGIN).clientLogin(ReportsLogins.REPORT_CLIENT_FOR_SLIDING_WINDOW);

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

    @Test
    public void successGetReportForPeriodThreeYearsAgo() {
        ReportsData reportsData = api.userSteps.reportsSteps().callReportsXml(
                new ReportDefinitionMap()
                        .withDefaultReportWithTypeAndUniqueReportName(ReportTypeEnum.CRITERIA_PERFORMANCE_REPORT)
                        .withCustomDates(VALID_BOUNDARY_DAY, VALID_BOUNDARY_DAY)
        );
        assertThat("вернулся непустой отчет", reportsData.getReportsLines(), not(empty()));
    }

    @Test
    public void successGetReportForPeriodWithStartDateEarlyThanThreeYearsAgo() {
        ReportsData reportsData = api.userSteps.reportsSteps().callReportsXml(
                new ReportDefinitionMap()
                        .withDefaultReportWithTypeAndUniqueReportName(ReportTypeEnum.CRITERIA_PERFORMANCE_REPORT)
                        .withCustomDates(INVALID_BOUNDARY_DAY, VALID_BOUNDARY_DAY)
        );
        assertThat("вернулся непустой отчет", reportsData.getReportsLines(), not(empty()));
    }

    @Test
    public void tryGetReportForPeriodEarlyThanThreeYearsAgo() {
        api.userSteps.reportsSteps().expectXmlErrorOnReports(
                new ReportDefinitionMap()
                        .withDefaultReportWithTypeAndUniqueReportName(ReportTypeEnum.CRITERIA_PERFORMANCE_REPORT)
                        .withCustomDates(INVALID_BOUNDARY_DAY, INVALID_BOUNDARY_DAY),
                new Api5Error(
                        4001,
                        Api5ErrorDetails.REPORTS_DATE_RANGE_OUT_OF_SLIDING_WINDOW,
                        ReportTypeEnum.CRITERIA_PERFORMANCE_REPORT,
                        capitalize(SelectionCriteriaMap.DATE_TO),
                        VALID_BOUNDARY_DAY.toString(ReportsData.DATE_FORMAT)
                )
        );
    }

    @Test
    public void compareReportsDataForPeriodThreeYearsAgo() {
        DateTime dateFrom = VALID_BOUNDARY_DAY.minusMonths(1);
        DateTime dateTo = VALID_BOUNDARY_DAY.plusMonths(1);
        ReportsData expectedReportsData = api.userSteps.reportsSteps().callReportsXml(
                new ReportDefinitionMap()
                        .withDefaultCustomReportWithUniqueReportName()
                        .withReportType(ReportTypeEnum.CRITERIA_PERFORMANCE_REPORT)
                        .withCustomDates(VALID_BOUNDARY_DAY, dateTo)
                        .withFieldNames(FieldEnum.CLICKS, FieldEnum.IMPRESSIONS)
        );
        assumeThat("вернулся непустой отчет", expectedReportsData.getReportsLines(), not(empty()));
        ReportsData reportsData = api.userSteps.reportsSteps().callReportsXml(
                new ReportDefinitionMap()
                        .withDefaultCustomReportWithUniqueReportName()
                        .withReportType(ReportTypeEnum.CRITERIA_PERFORMANCE_REPORT)
                        .withCustomDates(dateFrom, dateTo)
                        .withFieldNames(FieldEnum.CLICKS, FieldEnum.IMPRESSIONS)
        );
        assertThat("получили правильные данные", reportsData.getReportsLines(), beanDiffer(expectedReportsData.getReportsLines()));
    }
}
