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

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.BannersPerformance;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.Phrases;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannersPerformanceRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannersRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.PhrasesRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
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.AdUpdateItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppAdBuilderAdAddMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppAdBuilderAdUpdateMap;
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.Tag;
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.irt.testutils.beandiffer2.BeanDifferMatcher.beanDiffer;

/**
 * https://st.yandex-team.ru/DIRECT-71573
 */
@Aqua.Test
@Features(AdsFeatures.UPDATE)
@Description("Проверка сохранения в БД ГО, создаваемого на основе креатива")
@Issue("https://st.yandex-team.ru/DIRECT-58369")
@Tag(TagDictionary.TRUNK)
public class UpdateMobileAppAdBuilderAdCheckDbTest {
    private static String LOGIN = AdsLogins.CLIENT47;

    private static DirectJooqDbSteps directJooqDbSteps;
    private static PhrasesRecord phrasesBeforeUpdate;
    private static PhrasesRecord phrasesAfterUpdate;
    private static BannersRecord bannersBeforeUpdate;
    private static BannersRecord bannersAfterUpdate;
    private static BannersPerformanceRecord bannerPerformanceBeforeUpdate;
    private static BannersPerformanceRecord bannerPerformanceAfterUpdate;

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

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

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


    @BeforeClass
    public static void initTest() {
        api.as(LOGIN).userSteps.clientFakeSteps().fakeClearClientSpentUnits(LOGIN);
        Long campaignId = api.userSteps.campaignSteps().addDefaultMobileAppCampaign();
        Long adGroupId = api.userSteps.adGroupsSteps().addDefaultMobileGroup(campaignId);
        directJooqDbSteps = api.userSteps.getDarkSideSteps().getDirectJooqDbSteps().useShardForLogin(LOGIN);
        Long creativeIdForAdd = directJooqDbSteps.perfCreativesSteps().saveDefaultCanvasCreativesForClient(
                Long.parseLong(User.get(LOGIN).getClientID()));
        Long adId = api.userSteps.adsSteps().addAd(
                new AdAddItemMap()
                        .withAdGroupId(adGroupId)
                        .withMobileAppAdBuilderAd(
                                new MobileAppAdBuilderAdAddMap()
                                        .defaultMobileAppAdBuilderAd(creativeIdForAdd)
                        )
        );

        bannersBeforeUpdate = directJooqDbSteps.bannersSteps().getBanner(adId);
        bannerPerformanceBeforeUpdate =
                directJooqDbSteps.bannersPerformanceSteps().getBannersPerformance(adId, creativeIdForAdd);
        phrasesBeforeUpdate = directJooqDbSteps.adGroupsSteps().getPhrases(adGroupId);

        Long creativeIdForUpdate = api.userSteps.getDirectJooqDbSteps()
                .useShardForLogin(LOGIN).perfCreativesSteps().saveDefaultCanvasCreativesForClient(
                        Long.parseLong(User.get(LOGIN).getClientID()));
        api.userSteps.adsSteps().shouldGetResultOnUpdate(
                new UpdateRequestMap().withAds(new AdUpdateItemMap()
                        .withId(adId)
                        .withMobileAppAdBuilderAd(
                                new MobileAppAdBuilderAdUpdateMap()
                                        .withCreative(creativeIdForUpdate))),
                ExpectedResult.success());

        bannersAfterUpdate = directJooqDbSteps.bannersSteps().getBanner(adId);
        bannerPerformanceAfterUpdate =
                directJooqDbSteps.bannersPerformanceSteps().getBannersPerformance(adId, creativeIdForUpdate);
        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()),
                                BeanFieldPath.newPath(Banners.BANNERS.BODY.getName())
                        )));
    }

    @Test
    public void checkPpcBannerPerformanceAfterUpdateAd(){
        assertThat("в объявлении не изменилось ничего лишнего",
                bannerPerformanceAfterUpdate.intoMap(), beanDiffer(bannerPerformanceBeforeUpdate.intoMap())   .useCompareStrategy(DefaultCompareStrategies.allFieldsExcept(
                        BeanFieldPath.newPath(BannersPerformance.BANNERS_PERFORMANCE.CREATIVE_ID.getName())
                )));
    }
}
