package ru.yandex.autotests.direct.api.ads.update.mobileappimagead;

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.tables.Banners;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.Images;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.Phrases;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannerImagesRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannersRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.ImagesRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.PhrasesRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.ads.AdAddItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.AdUpdateItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppImageAdAddMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppImageAdUpdateMap;
import ru.yandex.autotests.directapi.model.api5.ads.UpdateRequestMap;
import ru.yandex.autotests.directapi.model.api5.general.ExpectedResult;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.irt.testutils.beandiffer2.beanfield.BeanFieldPath;
import ru.yandex.autotests.irt.testutils.beandiffer2.comparestrategy.defaultcomparestrategy.DefaultCompareStrategies;
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.nullValue;
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 ginger on 03.10.16.
 * https://st.yandex-team.ru/TESTIRT-10266
 */
@Aqua.Test
@Features(AdsFeatures.UPDATE)
@Description("Обновление объявления и проверка его состояния в базе")
@Issue("https://st.yandex-team.ru/DIRECT-58442")
public class UpdateAdsAndCheckDBTest {
    private static final String CLIENT = AdsLogins.CLIENT;
    private static Long adId;
    private static PhrasesRecord phrasesBeforeUpdate;
    private static PhrasesRecord phrasesAfterUpdate;
    private static BannersRecord bannersBeforeUpdate;
    private static BannersRecord bannersAfterUpdate;
    private static ImagesRecord imagesBeforeUpdate;
    private static ImagesRecord imagesAfterUpdate;

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

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

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

    private static DirectJooqDbSteps directJooqDbSteps = api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT);

    @BeforeClass
    public static void prepareData() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(CLIENT);
        Long campaignId = api.userSteps.campaignSteps().addDefaultMobileAppCampaign();
        Long adGroupId = api.userSteps.adGroupsSteps().addDefaultMobileGroup(campaignId);
        String adImageHashForAdd = api.userSteps.imagesStepsV5().addImageAdAdImage(2);
        adId = api.userSteps.adsSteps().addAd(
                new AdAddItemMap()
                        .withAdGroupId(adGroupId)
                        .withMobileAppImageAd(
                                new MobileAppImageAdAddMap()
                                        .defaultMobileAppImageAd(adImageHashForAdd)
                        )
        );

        BannerImagesRecord bannerImagesBeforeUpdate = directJooqDbSteps.imagesSteps().getBannerImagesByBid(adId);
        assumeThat("отсутствует запись в banner_images", bannerImagesBeforeUpdate, nullValue());

        bannersBeforeUpdate = directJooqDbSteps.bannersSteps().getBanner(adId);
        imagesBeforeUpdate = directJooqDbSteps.imagesSteps().getImagesRecords(campaignId, adGroupId, adId);
        phrasesBeforeUpdate = directJooqDbSteps.adGroupsSteps().getPhrases(adGroupId);

        String adImageHashForUpdate = api.userSteps.imagesStepsV5().addImageAdAdImage(3);
        api.userSteps.adsSteps().shouldGetResultOnUpdate(
                new UpdateRequestMap().withAds(new AdUpdateItemMap()
                        .withId(adId)
                        .withMobileAppImageAd(new MobileAppImageAdUpdateMap().withAdImageHash(adImageHashForUpdate))),
                ExpectedResult.success());

        BannerImagesRecord bannerImagesAfterUpdate = directJooqDbSteps.imagesSteps().getBannerImagesByBid(adId);
        assumeThat("отсутствует запись в banner_images", bannerImagesAfterUpdate, nullValue());

        bannersAfterUpdate = directJooqDbSteps.bannersSteps().getBanner(adId);
        imagesAfterUpdate = directJooqDbSteps.imagesSteps().getImagesRecords(campaignId, adGroupId, adId);
        phrasesAfterUpdate = directJooqDbSteps.adGroupsSteps().getPhrases(adGroupId);
    }

    @Test
    public void checkPpcPhrasesAfterUpdateAd(){
        assertThat("в объявлении не изменилось ничего лишнего",
                phrasesAfterUpdate.intoMap(), beanDiffer(phrasesBeforeUpdate.intoMap())
                        .useCompareStrategy(DefaultCompareStrategies.allFieldsExcept(
                                BeanFieldPath.newPath(Phrases.PHRASES.LASTCHANGE.getName())
                        )));
    }

    @Test
    public void checkPpcBannersAfterUpdateAd(){
        assertThat("в объявлении не изменилось ничего лишнего",
                bannersAfterUpdate.intoMap(), beanDiffer(bannersBeforeUpdate.intoMap())
                        .useCompareStrategy(DefaultCompareStrategies.allFieldsExcept(
                                BeanFieldPath.newPath(Banners.BANNERS.LASTCHANGE.getName())
                        )));
    }

    @Test
    public void checkPpcImagesAfterUpdateAd(){
        assertThat("в объявлении не изменилось ничего лишнего",
                imagesAfterUpdate.intoMap(), beanDiffer(imagesBeforeUpdate.intoMap())
                        .useCompareStrategy(DefaultCompareStrategies.allFieldsExcept(
                                BeanFieldPath.newPath(Images.IMAGES.IMAGE_HASH.getName())
                        )));
    }
}
