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

import com.yandex.direct.api.v5.reports.FieldEnum;
import com.yandex.direct.api.v5.reports.FilterOperatorEnum;
import org.junit.ClassRule;
import org.junit.Test;
import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.directapi.ApiFeatures;
import ru.yandex.autotests.directapi.darkside.Logins;
import ru.yandex.autotests.directapi.darkside.connection.Semaphore;
import ru.yandex.autotests.directapi.model.api5.reports.*;
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.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 gerdler on 15.11.16.
 */
@Aqua.Test
@Description("Проверка создания оффлайн-отчетов")
@Issue("https://st.yandex-team.ru/TESTIRT-10480")
@Features({ReportsFeatures.OFFLINE_CUSTOM_REPORT, ApiFeatures.SMOKE})
public class OfflineReportSmokeTest {

    private static Long CAMPAIGN_ID_1 = 287660L;
    private static Long CAMPAIGN_ID_2 = 737321L;
    private final String DATE_FROM = "2016-11-01";
    private final String DATE_TO = "2016-11-06";

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

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

    @Test
    public void getOfflineReport() {
        ReportsData reportsData = api.userSteps.reportsSteps().callOfflineReportsXml(getReportDefinitionMap(CAMPAIGN_ID_1));
        assertThat("вернулся непустой отчёт", reportsData.getReportsLines(), not(empty()));
    }

    @Test
    public void getSameReportForRequestsWithEqualReportNames() {
        ReportDefinitionMap reportDefinitionMap = getReportDefinitionMap(CAMPAIGN_ID_1);
        ReportsData reportsData = api.userSteps.reportsSteps().callOfflineReportsXml(reportDefinitionMap);
        assumeThat("вернулся отчёт", reportsData.getReportsLines(), hasSize(greaterThan(0)));
        reportsData = api.userSteps.reportsSteps().callOfflineReportsXmlForPreviouslyGeneratedReport(
                getReportDefinitionMap(CAMPAIGN_ID_2).withReportName(reportDefinitionMap.getReportName())
        );
        assertThat("вернулся созданный ранее отчёт", reportsData.getReportsLines().get(0).getCampaignId(), equalTo(CAMPAIGN_ID_1));
    }

    @Test
    public void compareOnlineAndOfflineReportsData() {
        ReportDefinitionMap reportDefinitionMap = new ReportDefinitionMap()
                .withDefaultCustomReportWithUniqueReportName()
                .withCustomDatesAndCampaignIds(DATE_FROM, DATE_TO, CAMPAIGN_ID_1, CAMPAIGN_ID_2)
                .withFieldNames(
                        FieldEnum.DATE,
                        FieldEnum.AD_NETWORK_TYPE,
                        FieldEnum.AGE,
                        FieldEnum.IMPRESSIONS,
                        FieldEnum.CLICKS,
                        FieldEnum.AVG_CPC,
                        FieldEnum.AVG_CLICK_POSITION,
                        FieldEnum.COST_PER_CONVERSION ,
                        FieldEnum.AVG_IMPRESSION_POSITION,
                        FieldEnum.AVG_PAGEVIEWS ,
                        FieldEnum.BOUNCE_RATE,
                        FieldEnum.BOUNCES,
                        FieldEnum.PROFIT
                )
                .withPage(new PageMap().withLimit(200L));
        ReportsData onlineReportData = api.userSteps.reportsSteps().callOnlineReportsXml(reportDefinitionMap);
        assumeThat("вернулся отчёт", onlineReportData.getReportsLines(), hasSize(greaterThan(0)));
        ReportsData offlineReportData = api.userSteps.reportsSteps().callOfflineReportsXml(reportDefinitionMap.withUniqueReportName()
        );
        assertThat(
                "данные онлайн и офлайн отчетов совпадают",
                offlineReportData.getReportsLines(),
                beanDiffer(onlineReportData.getReportsLines())
        );
    }

    private ReportDefinitionMap getReportDefinitionMap(Long campaignId) {
        return new ReportDefinitionMap().withDefaultCustomReportWithUniqueReportName().withSelectionCriteria(
                getSelectionCriteriaMap(campaignId)
        );
    }

    private SelectionCriteriaMap getSelectionCriteriaMap(Long campaignId) {
        return new SelectionCriteriaMap().withFilter(
                new FilterItemMap().withField(FieldEnum.CAMPAIGN_ID)
                        .withOperator(FilterOperatorEnum.EQUALS)
                        .withValues(campaignId)
        );
    }
}
