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

import java.util.ArrayList;
import java.util.List;

import com.yandex.direct.api.v5.ads.AdFieldEnum;
import com.yandex.direct.api.v5.ads.AdGetItem;
import com.yandex.direct.api.v5.ads.AdSubtypeEnum;
import com.yandex.direct.api.v5.ads.AdTypeEnum;
import com.yandex.direct.api.v5.ads.GetResponse;
import com.yandex.direct.api.v5.ads.MobileAppCpcVideoAdBuilderAdFieldEnum;
import org.junit.Assert;
import org.junit.Before;
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.steps.DirectJooqDbSteps;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.ads.AdAddItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.AdBuilderAdGetItemMap;
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.model.api5.ads.MobileAppAdAddMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppCpcVideoAdBuilderAdAddMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppCpcVideoAdBuilderAdGetMap;
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 java.util.Collections.singletonList;
import static ru.yandex.autotests.direct.db.steps.PerfCreativesSteps.DEFAULT_LIVE_PREVIEW_URL;
import static ru.yandex.autotests.direct.db.steps.PerfCreativesSteps.DEFAULT_PREVIEW_URL;
import static ru.yandex.autotests.directapi.matchers.beans.version5.BeanDifferMatcherV5.beanDifferV5;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

/**
 * https://st.yandex-team.ru/DIRECT-132279
 */
@Aqua.Test
@Features(AdsFeatures.GET)
@Description("Проверка выборки кликовых видеообъявлений для РМП")
@Issue("https://st.yandex-team.ru/DIRECT-132279")
public class GetMobileAppCpcVideoAdBuilderAdTest {
    private static final String CLIENT = AdsLogins.CLIENT43;

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

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

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

    private Long adId;
    private Long adGroupId;
    private Long campaignId;
    private Long creativeId;

    @Before
    public void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(CLIENT);
        long clientId = Long.parseLong(User.get(CLIENT).getClientID());
        campaignId = api.userSteps.campaignSteps().addDefaultMobileAppCampaign();
        adGroupId = api.userSteps.adGroupsSteps().addDefaultMobileGroup(campaignId);
        DirectJooqDbSteps jooqDbSteps =
                api.userSteps.getDarkSideSteps().getDirectJooqDbSteps().useShardForLogin(CLIENT);

        creativeId = jooqDbSteps.perfCreativesSteps().saveDefaultCpcVideoCreative(clientId);

        adId = api.userSteps.adsSteps().addAd(
                new AdAddItemMap()
                        .withMobileAppCpcVideoAdBuilderAd(new MobileAppCpcVideoAdBuilderAdAddMap()
                                .withTrackingUrl(MobileAppCpcVideoAdBuilderAdAddMap.DEFAULT_TRACKING_URL)
                                .withCreative(creativeId)
                        )
                        .withAdGroupId(adGroupId)
        );
    }

    @Test
    public void getAdByAdId() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(
                new GetRequestMap().withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withIds(adId)
                ).withFieldNames(AdFieldEnum.ID)
                        .withMobileAppCpcAdVideoAdBuilderAdFieldNames(MobileAppCpcVideoAdBuilderAdFieldEnum.CREATIVE,
                                MobileAppCpcVideoAdBuilderAdFieldEnum.TRACKING_URL)
        );
        assertThat("вернулось правильное объявление", getResponse.getAds(),
                beanDifferV5(singletonList((AdGetItem)
                        new AdGetItemMap()
                                .withId(adId)
                                .withMobileAppCpcVideoAdBuilderAd(new MobileAppCpcVideoAdBuilderAdGetMap()
                                        .withTrackingUrl(MobileAppCpcVideoAdBuilderAdAddMap.DEFAULT_TRACKING_URL)
                                        .withCreative(new AdBuilderAdGetItemMap()
                                                .withThumbnailUrl(DEFAULT_PREVIEW_URL)
                                                .withPreviewUrl(DEFAULT_LIVE_PREVIEW_URL)
                                                .withCreativeId(creativeId)))
                                .getBean())));
    }

    @Test
    public void getAdByAdGroupId() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(
                new GetRequestMap().withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withAdGroupIds(adGroupId)
                ).withMobileAppCpcAdVideoAdBuilderAdFieldNames(MobileAppCpcVideoAdBuilderAdFieldEnum.CREATIVE)
                        .withFieldNames(AdFieldEnum.ID)
        );
        assertThat("вернулось правильное объявление", getResponse.getAds(),
                beanDifferV5(singletonList((AdGetItem) new AdGetItemMap()
                        .withId(adId)
                        .withMobileAppCpcVideoAdBuilderAd(
                                new MobileAppCpcVideoAdBuilderAdGetMap().withCreative(
                                        new AdBuilderAdGetItemMap()
                                                .withCreativeId(creativeId)
                                                .withThumbnailUrl(DEFAULT_PREVIEW_URL)
                                                .withPreviewUrl(DEFAULT_LIVE_PREVIEW_URL)
                                ))
                        .getBean())));
    }

    @Test
    public void getAdByCampaignId() {
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(
                new GetRequestMap().withSelectionCriteria(
                        new AdsSelectionCriteriaMap().withCampaignIds(campaignId)
                ).withMobileAppCpcAdVideoAdBuilderAdFieldNames(MobileAppCpcVideoAdBuilderAdFieldEnum.CREATIVE)
                        .withFieldNames(AdFieldEnum.ID)
        );
        assertThat("вернулось правильное объявление", getResponse.getAds(),
                beanDifferV5(singletonList((AdGetItem) new AdGetItemMap()
                        .withId(adId)
                        .withMobileAppCpcVideoAdBuilderAd(
                                new MobileAppCpcVideoAdBuilderAdGetMap().withCreative(
                                        new AdBuilderAdGetItemMap()
                                                .withCreativeId(creativeId)
                                                .withThumbnailUrl(DEFAULT_PREVIEW_URL)
                                                .withPreviewUrl(DEFAULT_LIVE_PREVIEW_URL)
                                ))
                        .getBean())));
    }

    /**
     * При запросе типа CPC_VIDEO_AD возвращается только cpc_video баннер РМП
     */
    @Test
    public void getCpcVideoAdsByCpcVideoType() {
        Long mobileAppAdId = api.userSteps.adsSteps().addAd(
                new AdAddItemMap()
                        .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd())
                        .withAdGroupId(adGroupId)
        );

        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(new AdsSelectionCriteriaMap()
                        .withIds(adId, mobileAppAdId)
                        .withTypes(AdTypeEnum.CPC_VIDEO_AD))
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.TYPE, AdFieldEnum.SUBTYPE));

        List<AdGetItem> expectAds = new ArrayList<>();
        expectAds.add((AdGetItem) new AdGetItemMap()
                .withId(adId)
                .withType(AdTypeEnum.CPC_VIDEO_AD)
                .withSubtype(AdSubtypeEnum.MOBILE_APP_CPC_VIDEO_AD_BUILDER_AD).getBean());

        Assert.assertThat("вернулось cpc_video объявление РМП",
                getResponse.getAds(), beanDifferV5(expectAds));
    }

    /**
     * При запросе типов MOBILE_APP_AD/CPC_VIDEO_AD возвращаются cpc_video и mobile_content баннеры РМП
     */
    @Test
    public void getMobileAppAndCpcVideoAdsByMobileAppAndCpcVideoTypes() {
        Long mobileAppAdId = api.userSteps.adsSteps().addAd(
                new AdAddItemMap()
                        .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd())
                        .withAdGroupId(adGroupId)
        );

        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(new AdsSelectionCriteriaMap()
                        .withIds(adId, mobileAppAdId)
                        .withTypes(AdTypeEnum.MOBILE_APP_AD, AdTypeEnum.CPC_VIDEO_AD))
                .withFieldNames(AdFieldEnum.ID, AdFieldEnum.TYPE));

        List<AdGetItem> expectAds = new ArrayList<>();
        expectAds.add((AdGetItem) new AdGetItemMap()
                .withId(adId)
                .withType(AdTypeEnum.CPC_VIDEO_AD).getBean());
        expectAds.add((AdGetItem) new AdGetItemMap()
                .withId(mobileAppAdId)
                .withType(AdTypeEnum.MOBILE_APP_AD).getBean());

        Assert.assertThat("вернулись mobile_content и cpc_video объявления РМП",
                getResponse.getAds(), beanDifferV5(expectAds));
    }
}
