package ru.yandex.autotests.directintapi.bstransport.main.imagead.transmit;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.BannerImagesFormatsImageType;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.ImagesStatusmoderate;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannerImagesFormatsRecord;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.darkside.Logins;
import ru.yandex.autotests.directapi.darkside.connection.Semaphore;
import ru.yandex.autotests.directapi.darkside.model.RunBsTransportScriptResponse;
import ru.yandex.autotests.directapi.darkside.model.bslogs.BannerTemplateId;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Banner;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Campaign;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Context;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Resources;
import ru.yandex.autotests.directapi.enums.AdGroupType;
import ru.yandex.autotests.directapi.enums.BannerType;
import ru.yandex.autotests.directapi.enums.CampaignType;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directintapi.bstransport.FeatureNames;
import ru.yandex.autotests.directintapi.bstransport.StoriesNames;
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.allure.annotations.Step;
import ru.yandex.qatools.allure.annotations.Stories;
import ru.yandex.qatools.allure.annotations.Title;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.iterableWithSize;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNull.notNullValue;
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 buhter on 16/06/16.
 * https://st.yandex-team.ru/TESTIRT-9352
 * https://st.yandex-team.ru/TESTIRT-10837
 */
@Aqua.Test
@Tag(TagDictionary.RELEASE)
@Tag(TagDictionary.TRUNK)
@Title(" Отправка поля Banner.MediaImage и Banner.Resources.MediaImage для графического баннера")
@Stories(StoriesNames.IMAGE_AD_BANNER_ACTION_SEND)
@Features(FeatureNames.IMAGE_ADS)
@Issue("https://st.yandex-team.ru/DIRECT-54196")
@RunWith(Parameterized.class)
public class BsTransportNewImageAdMediaImageTest {

    private static final String LOGIN = Logins.LOGIN_TRANSPORT_IMG_AD;

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

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

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

    private static int shard;

    @Parameterized.Parameter(0)
    public CampaignType campaignType;

    @Parameterized.Parameter(1)
    public AdGroupType adGroupType;

    @Parameterized.Parameter(2)
    public String imageHash;

    private Banner banner;
    private String[] expectedMediaImage;

    @Parameterized.Parameters(name = "Тип кампаниии: {0}, тип группы: {1}, hash: {2}")
    public static Collection<Object[]> data() {
        shard = api.userSteps.clientFakeSteps().getUserShard(LOGIN);
        List<String> images = api.userSteps.imagesStepsV5().adImagesGetAllHashes(LOGIN);
        assumeThat("у пользователя не менее 2 картинок", images, iterableWithSize(greaterThanOrEqualTo(2)));
        assumeThat("выбрана картинка правильного формата", api.userSteps.getDirectJooqDbSteps().useShard(shard)
                        .imagesSteps().getBannerImagesFormatsRecords(images.get(0)).getImageType(),
                equalTo(BannerImagesFormatsImageType.image_ad));
        assumeThat("выбрана картинка правильного формата", api.userSteps.getDirectJooqDbSteps().useShard(shard)
                        .imagesSteps().getBannerImagesFormatsRecords(images.get(1)).getImageType(),
                equalTo(BannerImagesFormatsImageType.image_ad));
        Object[][] data = new Object[][]{
                {CampaignType.TEXT, AdGroupType.BASE, images.get(0)},
                {CampaignType.MOBILE_CONTENT, AdGroupType.MOBILE_CONTENT, images.get(0)},
                {CampaignType.TEXT, AdGroupType.BASE, images.get(1)},
                {CampaignType.MOBILE_CONTENT, AdGroupType.MOBILE_CONTENT, images.get(1)}
        };
        return Arrays.asList(data);
    }

    @Before
    @Step("Подготовка тестовых данных")
    public void init() {
        Long cid = api.userSteps.campaignSteps().addDefaultCampaign(campaignType);
        Long pid = api.userSteps.adGroupsSteps().addDefaultGroup(cid, adGroupType);
        Long bid = api.userSteps.adsSteps().addAdWithAdImageHash(pid, adGroupType, BannerType.IMAGE_AD, imageHash);

        Long keywordId = api.userSteps.keywordsSteps().addDefaultKeyword(pid);

        api.userSteps.campaignFakeSteps().makeNewCampaignReadyForSendingToBS(cid);
        api.userSteps.groupFakeSteps().makeGroupFullyModerated(pid);
        api.userSteps.bannersFakeSteps().makeBannerFullyModerated(bid);
        api.userSteps.phrasesFakeSteps().makeKeywordModerated(keywordId);
        api.userSteps.getDarkSideSteps().getDirectJooqDbSteps().useShard(shard).imagesSteps()
                .setImageStatusModerate(bid, imageHash, ImagesStatusmoderate.Yes);
        RunBsTransportScriptResponse resp
                = api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp, 0, cid);
        Context context = campaign != null ? campaign.getContext(pid) : null;
        banner = context != null ? context.getBanner(bid) : null;
        assumeThat("в БК отправлен графический баннер", banner, notNullValue());
        BannerImagesFormatsRecord bannerImagesFormatsRecord = api.userSteps.getDirectJooqDbSteps()
                .useShard(shard).imagesSteps().getBannerImagesFormatsRecords(imageHash);
        assumeThat("по хэшу нашлась запись", bannerImagesFormatsRecord, Matchers.notNullValue());

        expectedMediaImage = getExpectedMediaImage(bannerImagesFormatsRecord);
    }

    private String[] getExpectedMediaImage(BannerImagesFormatsRecord bannerImagesFormatsRecord) {
        String mdsUrl = new StringBuilder().append("//")
                .append(bannerImagesFormatsRecord.getAvatarsHost().getLiteral())
                .append("/get-")
                .append(bannerImagesFormatsRecord.getNamespace().getLiteral())
                .append("/")
                .append(bannerImagesFormatsRecord.getMdsGroupId()).append("/")
                .append(bannerImagesFormatsRecord.getImageHash())
                .append("/orig")
                .toString();

        return
                new String[]{
                        mdsUrl,
                        String.valueOf(bannerImagesFormatsRecord.getWidth()),
                        String.valueOf(bannerImagesFormatsRecord.getHeight())
                };
    }

    @Test
    @Title("Проверяем параметры отправляемого графического баннера")
    @Description("Проверяем следующие параметры на уровне баннера: IsMediaImage, MediaImage, TemplateID, Resources->MediaImage")
    public void testSendingToBsBannerMediaImage() {
        Banner expectedBanner = new Banner()
                .withIsMediaImage(1)
                .withMediaImage(expectedMediaImage)
                .withResources(new Resources().withMediaImage(expectedMediaImage))
                .withTemplateId(BannerTemplateId.MEDIA_IMAGE_TEMPLATE_ID.value());

        assertThat("параметры графического баннера соотв. ожиданиям",
                banner,
                beanDiffer(expectedBanner).useCompareStrategy(DefaultCompareStrategies.onlyExpectedFields()));
    }
}

