package ru.yandex.autotests.directintapi.bstransport.main.campaign.parameters.impressionstandard;

import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

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.db.models.jooq.ppc.tables.records.CampOptionsRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
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.clientdata.Campaign;
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.qatools.Tag;
import ru.yandex.qatools.allure.annotations.Features;
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.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

@Aqua.Test
@Tag(TagDictionary.TRUNK)
@Tag(TagDictionary.RELEASE)
@Title("Транспорт: проверка отправки параметров ImpressionStandardTime/ImpressionStandardType")
@Stories(StoriesNames.CAMPAIGN_PARAMS_IMPRESSION_STANDARD)
@Features({FeatureNames.CAMPAIGNS})
@ParametersAreNonnullByDefault
public class BsTransportOfImpressionStandardTimeTest {
    private static final String login = Logins.LOGIN_TRANSPORT;

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

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

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

    DirectJooqDbSteps jooqDbSteps;
    int shard;
    long cid;
    long clientId;

    @Before
    public void before() {
        shard = api.userSteps.clientFakeSteps().getUserShard(login);
        clientId = Long.parseLong(api.userSteps.clientFakeSteps().getClientData(login).getClientID());
        jooqDbSteps = api.userSteps.getDirectJooqDbSteps().useShard(shard);
        cid = api.userSteps.campaignSteps().addDefaultCpmBannerCampaign();
        api.userSteps.campaignFakeSteps().makeNewCampaignReadyForSendingToBS(cid);
    }

    @Test
    @Title("Отправка параметров ImpressionStandardTime/Type, если выбран стандарт определения видимости MRC")
    public void testImpressionStandardTime_MRCStandard() {
        setImpressionStandardTime(cid, Short.valueOf("1000"));
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp,
                cid);
        assertThat("отправляется правильное значение ImpressionStandardTime",
                campaign.getImpressionStandardTime(), equalTo(Short.valueOf("1000")));
        assertThat("отправляется правильное значение ImpressionStandardType",
                campaign.getImpressionStandardType(), equalTo("mrc"));
    }

    @Test
    @Title("Отправка параметров ImpressionStandardTime/Type, если выбран стандарт определения видимости Яндекс")
    public void testImpressionStandardTime_YandexStandard() {
        setImpressionStandardTime(cid, Short.valueOf("2000"));
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp,
                cid);
        assertThat("отправляется правильное значение ImpressionStandardTime",
                campaign.getImpressionStandardTime(), equalTo(Short.valueOf("2000")));
        assertThat("отправляется правильное значение ImpressionStandardTime",
                campaign.getImpressionStandardType(), equalTo("yandex"));
    }

    @Test
    @Title("Неотправка параметров ImpressionStandardTime/Type, если время явно не задано")
    public void testImpressionStandardTime_NoStandard() {
        setImpressionStandardTime(cid, null);
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Map<String, ?> rawClientDataLogRequestForCampaign =
                api.userSteps.getDarkSideSteps().getTransportSteps().getRawClientDataLogRequestForCampaign(resp, cid,
                        0);
        assertThat("поле ImpressionStandardTime не отправляется",
                rawClientDataLogRequestForCampaign.keySet(), not(hasItem("ImpressionStandardTime")));
        assertThat("поле ImpressionStandardType не отправляется",
                rawClientDataLogRequestForCampaign.keySet(), not(hasItem("ImpressionStandardType")));
    }

    private void setImpressionStandardTime(long cid, @Nullable Short time) {
        CampOptionsRecord co = jooqDbSteps.campaignsSteps().getCampOptionsById(cid);
        co.setImpressionStandardTime(time);
        jooqDbSteps.campaignsSteps().updateCampOptions(co);
    }
}
