package ru.yandex.autotests.direct.api.ads.get.textimagead;

import java.util.Arrays;

import com.yandex.direct.api.v5.ads.AdFieldEnum;
import com.yandex.direct.api.v5.ads.AdGetItem;
import com.yandex.direct.api.v5.ads.AdStatusSelectionEnum;
import com.yandex.direct.api.v5.ads.GetResponse;
import com.yandex.direct.api.v5.general.StatusEnum;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;

import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.api.ads.AdsFeatures;
import ru.yandex.autotests.direct.api.ads.AdsLogins;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.BannersStatusmoderate;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.BannersStatuspostmoderate;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.ImagesStatusmoderate;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannersRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.ads.AdGetItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.AdsSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.ads.GetRequestMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
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.junit.Assert.assertThat;
import static ru.yandex.autotests.directapi.matchers.beans.version5.BeanDifferMatcherV5.beanDifferV5;

/**
 * Created by gerdler on 08.07.16.
 * https://st.yandex-team.ru/TESTIRT-9322
 */
@Aqua.Test
@Features(AdsFeatures.GET)
@Description("Проверка выборки текстовых графических объявлений по статусам")
@Issue("https://st.yandex-team.ru/DIRECT-54753")
public class GetTextImageAdByStatusTest {
    private static String client = AdsLogins.CLIENT43;

    @ClassRule
    public static ApiSteps api = new ApiSteps().as(client);

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

    @Rule
    public Trashman trasher = new Trashman(api);

    private static Long adGroupId;
    private static Long draftAdId, moderationAdId1, moderationAdId2, preacceptedAdId, rejectedAdId1, rejectedAdId2, rejectedAdId3, acceptedAdId;
    private static String adImageHash;
    private static DirectJooqDbSteps jooqDbSteps;

    @BeforeClass
    public static void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        Long campaignId = api.userSteps.campaignSteps().addDefaultTextCampaign();
        adGroupId = api.userSteps.adGroupsSteps().addDefaultGroup(campaignId);
        adImageHash = api.userSteps.imagesStepsV5().addImageAdAdImage(3);
        jooqDbSteps = api.userSteps.getDarkSideSteps().getDirectJooqDbSteps().useShardForLogin(client);

        draftAdId = addAd(BannersStatusmoderate.New, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.New);
        moderationAdId1 = addAd(BannersStatusmoderate.Yes, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.Sent);
        moderationAdId2 = addAd(BannersStatusmoderate.Sent, BannersStatuspostmoderate.No, ImagesStatusmoderate.Yes);
        preacceptedAdId = addAd(BannersStatusmoderate.Sent, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.Yes);
        rejectedAdId1 = addAd(BannersStatusmoderate.Yes, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.No);
        rejectedAdId2 = addAd(BannersStatusmoderate.No, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.No);
        rejectedAdId3 = addAd(BannersStatusmoderate.Sent, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.No);
        acceptedAdId = addAd(BannersStatusmoderate.Yes, BannersStatuspostmoderate.Yes, ImagesStatusmoderate.Yes);
    }

    private static Long addAd(BannersStatusmoderate bannerStatusmoderate, BannersStatuspostmoderate bannerStatuspostmoderate, ImagesStatusmoderate imageStatusmoderate) {
        Long adId = api.userSteps.adsSteps().addDefaultTextImageAd(adGroupId, adImageHash);
        jooqDbSteps.bannersSteps().updateBanners(
                new BannersRecord().setBid(adId).setStatusmoderate(bannerStatusmoderate).setStatuspostmoderate(bannerStatuspostmoderate)
        );
        jooqDbSteps.imagesSteps().setImageStatusModerate(adId, adImageHash, imageStatusmoderate);
        return adId;
    }

    @Test
    public void getAdsAndCheckStatuses() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(new AdsSelectionCriteriaMap()
                        .withIds(
                                draftAdId,
                                moderationAdId1,
                                moderationAdId2,
                                preacceptedAdId,
                                rejectedAdId1,
                                rejectedAdId2,
                                rejectedAdId3,
                                acceptedAdId
                        ))

                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("объявления имеют правильный статус модерации", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap().withId(draftAdId).withStatus(StatusEnum.DRAFT).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(moderationAdId1).withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(moderationAdId2).withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(preacceptedAdId).withStatus(StatusEnum.PREACCEPTED).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(rejectedAdId1).withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(rejectedAdId2).withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(rejectedAdId3).withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap().withId(acceptedAdId).withStatus(StatusEnum.ACCEPTED).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithDraftStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId).withStatuses(AdStatusSelectionEnum.DRAFT)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(), beanDifferV5(
                Arrays.asList((AdGetItem) new AdGetItemMap()
                        .withId(draftAdId)
                        .withStatus(StatusEnum.DRAFT).getBean())));
    }

    @Test
    public void getAdsWithModerationStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId).withStatuses(AdStatusSelectionEnum.MODERATION)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(moderationAdId1)
                                        .withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(moderationAdId2)
                                        .withStatus(StatusEnum.MODERATION).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithPreacceptedStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId).withStatuses(AdStatusSelectionEnum.PREACCEPTED)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(preacceptedAdId)
                                        .withStatus(StatusEnum.PREACCEPTED).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithAcceptedStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId).withStatuses(AdStatusSelectionEnum.ACCEPTED)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(acceptedAdId)
                                        .withStatus(StatusEnum.ACCEPTED).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithRejectedStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId).withStatuses(AdStatusSelectionEnum.REJECTED)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId1)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId2)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId3)
                                        .withStatus(StatusEnum.REJECTED).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithDraftAndRejectedStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId).withStatuses(AdStatusSelectionEnum.REJECTED, AdStatusSelectionEnum.DRAFT)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(draftAdId)
                                        .withStatus(StatusEnum.DRAFT).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId1)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId2)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId3)
                                        .withStatus(StatusEnum.REJECTED).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithModerationAndPreacceptedAndAcceptedStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap()
                                .withAdGroupIds(adGroupId)
                                .withStatuses(AdStatusSelectionEnum.MODERATION, AdStatusSelectionEnum.PREACCEPTED, AdStatusSelectionEnum.ACCEPTED)
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(moderationAdId1)
                                        .withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(moderationAdId2)
                                        .withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(preacceptedAdId)
                                        .withStatus(StatusEnum.PREACCEPTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(acceptedAdId)
                                        .withStatus(StatusEnum.ACCEPTED).getBean()
                        )
                )
        );
    }

    @Test
    public void getAdsWithAllStatus() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(
                        new AdsSelectionCriteriaMap()
                                .withAdGroupIds(adGroupId)
                                .withStatuses(
                                        AdStatusSelectionEnum.DRAFT,
                                        AdStatusSelectionEnum.MODERATION,
                                        AdStatusSelectionEnum.PREACCEPTED,
                                        AdStatusSelectionEnum.ACCEPTED,
                                        AdStatusSelectionEnum.REJECTED
                                )
                )
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.STATUS)
        );
        assertThat("вернулись правильные объявления", getResponse.getAds(),
                beanDifferV5(
                        Arrays.asList(
                                (AdGetItem) new AdGetItemMap()
                                        .withId(draftAdId)
                                        .withStatus(StatusEnum.DRAFT).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(moderationAdId1)
                                        .withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(moderationAdId2)
                                        .withStatus(StatusEnum.MODERATION).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(preacceptedAdId)
                                        .withStatus(StatusEnum.PREACCEPTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId1)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId2)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(rejectedAdId3)
                                        .withStatus(StatusEnum.REJECTED).getBean(),
                                (AdGetItem) new AdGetItemMap()
                                        .withId(acceptedAdId)
                                        .withStatus(StatusEnum.ACCEPTED).getBean()
                        )
                )
        );
    }

}
