package ru.yandex.autotests.directapi.reports;

import com.yandex.direct.api.v5.reports.DateRangeTypeEnum;
import org.joda.time.DateTime;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
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.ReportProcessingMode;
import ru.yandex.autotests.directapi.model.api5.reports.ReportResponse;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

/**
 * Created by gerdler on 23.12.16.
 * https://st.yandex-team.ru/TESTIRT-10825
 */
@Aqua.Test
@Description("Проверка корректной работы значений auto и null заголовка Processing-Mode")
@Issue("https://st.yandex-team.ru/DIRECT-61621")
@Features(ReportsFeatures.FORCE_OFFLINE)
@RunWith(Parameterized.class)
public class ForceOfflineTest {

    private final static Long CAMPAIGN_ID = 7446973L;
    private final static List<Long> TEN_CAMPAIGN_IDS = Arrays.asList(
            7446885L, 7446965L, 7446967L, 7446969L, 7446970L,
            7446972L, 7446975L, 7446976L, 7446977L, 7446979L
    );
    private final static DateTime DATE_TO_SEVEN_DAYS_LATER = DateTime.now();
    private final static DateTime DATE_TO_SIX_DAYS_LATER = DATE_TO_SEVEN_DAYS_LATER.minusDays(1);
    private final static DateTime DATE_FROM = DATE_TO_SIX_DAYS_LATER.minusDays(6);

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

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

    @Parameterized.Parameter(0)
    public ReportProcessingMode reportProcessingMode;

    @Parameterized.Parameters(name = "processing mode {0}")
    public static Collection testData() {
        Object[][] data = new Object[][]{
                {ReportProcessingMode.AUTO},
                {null},
        };
        return Arrays.asList(data);
    }
    @Test
    public void checkForceOfflineSearchQueryPerformanceReport() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultSearchQueryReportWithUniqueReportName()
                .withDateRangeType(DateRangeTypeEnum.TODAY)
                .withCampaignIds(CAMPAIGN_ID);
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsXmlGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме офлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.OFFLINE));
    }

    @Test
    public void checkForceOfflineCustomReportForAllTime() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withDateRangeType(DateRangeTypeEnum.ALL_TIME)
                .withCampaignIds(CAMPAIGN_ID);
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsXmlGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме офлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.OFFLINE));
    }

    @Test
    public void checkForceOfflineCustomReportForAllTimeJson() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withDateRangeType(DateRangeTypeEnum.ALL_TIME)
                .withCampaignIds(CAMPAIGN_ID);
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsJsonGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме офлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.OFFLINE));
    }


    @Test
    public void checkForceOfflineCustomReportForSevenDays() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withCustomDatesAndCampaignIds(DATE_FROM, DATE_TO_SIX_DAYS_LATER, CAMPAIGN_ID);
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsXmlGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме онлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.ONLINE));
    }

    @Test
    public void checkForceOfflineCustomReportForSevenDaysJson() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withCustomDatesAndCampaignIds(DATE_FROM, DATE_TO_SIX_DAYS_LATER, CAMPAIGN_ID);
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsJsonGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме онлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.ONLINE));
    }

    @Test
    public void checkForceOfflineCustomReportForMoreThanSevenDays() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withCustomDatesAndCampaignIds(DATE_FROM, DATE_TO_SEVEN_DAYS_LATER, CAMPAIGN_ID);
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsXmlGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме офлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.OFFLINE));
    }

    @Test
    public void checkForceOfflineCustomReportForTenCampaigns() {

        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withDateRangeType(DateRangeTypeEnum.TODAY)
                .withCampaignIds(TEN_CAMPAIGN_IDS.toArray(new Long[TEN_CAMPAIGN_IDS.size()]));
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsXmlGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме онлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.ONLINE));
    }

    @Test
    public void checkForceOfflineCustomReportForMoreThanTenCampaigns() {
        List<Long> elevenCampaignIds = new ArrayList(TEN_CAMPAIGN_IDS);
        elevenCampaignIds.add(CAMPAIGN_ID);
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withDateRangeType(DateRangeTypeEnum.TODAY)
                .withCampaignIds(elevenCampaignIds.toArray(new Long[elevenCampaignIds.size()]));
        ReportResponse reportResponse = api.userSteps.reportsSteps().callReportsXmlGetReportResponse(reportDefinitionMap, reportProcessingMode);

        assertThat("отчет создался в режиме офлайн", reportResponse.getActualProcessingMode(), equalTo(ReportProcessingMode.OFFLINE));
    }
}
