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

import java.math.BigDecimal;
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("Транспорт: проверка отправки параметров EshowsBannerRate")
@Stories(StoriesNames.CAMPAIGN_PARAMS_ESHOWS)
@Features({FeatureNames.CAMPAIGNS})
@ParametersAreNonnullByDefault
public class BsTransportOfEshowsRate {
    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("Отправка параметра EshowsBannerRate")
    public void testEshowsBannerRateSent() {
        setEshowsBannerRate(cid, new BigDecimal("0.15"));
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp,
                cid);
        assertThat("отправляется правильное значение EshowsBannerRate",
                campaign.getEshowsBannerRate(), equalTo(new BigDecimal("0.15")));

        Map<String, ?> rawClientDataLogRequestForCampaign =
                api.userSteps.getDarkSideSteps().getTransportSteps().getRawClientDataLogRequestForCampaign(resp, cid,
                        0);
        assertThat("параметр EshowsBannerRate имеет правильный тип",
                rawClientDataLogRequestForCampaign.get("EshowsBannerRate").getClass().getSimpleName(),
                equalTo("Double")
        );
    }

    @Test
    @Title("Отправка параметра EshowsVideoRate")
    public void testEshowsVideoRateSent() {
        setEshowsVideoRate(cid, new BigDecimal("0.15"));
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp,
                cid);
        assertThat("отправляется правильное значение EshowsVideoRate",
                campaign.getEshowsVideoRate(), equalTo(new BigDecimal("0.15")));

        Map<String, ?> rawClientDataLogRequestForCampaign =
                api.userSteps.getDarkSideSteps().getTransportSteps().getRawClientDataLogRequestForCampaign(resp, cid,
                        0);
        assertThat("параметр EshowsVideoRate имеет правильный тип",
                rawClientDataLogRequestForCampaign.get("EshowsVideoRate").getClass().getSimpleName(),
                equalTo("Double")
        );
    }

    @Test
    @Title("Отправка параметра EshowsVideoType long_clicks")
    public void testEshowsVideoTypeLongClicksSent() {
        setEshowsVideoType(cid, "long_clicks");
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp,
                cid);
        assertThat("отправляется правильное значение EshowsVideoType",
                campaign.getEshowsVideoType(), equalTo("LongClicks"));
    }

    @Test
    @Title("Отправка параметра EshowsVideoType completes")
    public void testEshowsVideoTypeCompletesSent() {
        setEshowsVideoType(cid, "completes");
        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Campaign campaign = api.userSteps.getDarkSideSteps().getTransportSteps().getClientDataRequestCampaign(resp,
                cid);
        assertThat("отправляется правильное значение EshowsVideoType",
                campaign.getEshowsVideoType(), equalTo("Completes"));
    }

    @Test
    @Title("Неотправка параметров EshowsBannerRate и EshowsVideoRate")
    public void testEshowsRatesNotSent() {
        setEshowsBannerRate(cid, null);
        setEshowsVideoRate(cid, null);
        setEshowsVideoType(cid, null);

        RunBsTransportScriptResponse resp =
                api.userSteps.getDarkSideSteps().getTransportSteps().sendNewCampaign(shard, cid);
        Map<String, ?> rawClientDataLogRequestForCampaign =
                api.userSteps.getDarkSideSteps().getTransportSteps().getRawClientDataLogRequestForCampaign(resp, cid,
                        0);
        assertThat("поле EshowsBannerRate не отправляется",
                rawClientDataLogRequestForCampaign.keySet(), not(hasItem("EshowsBannerRate")));
        assertThat("поле EshowsVideoRate не отправляется",
                rawClientDataLogRequestForCampaign.keySet(), not(hasItem("EshowsVideoRate")));
        assertThat("поле EshowsVideoType не отправляется",
                rawClientDataLogRequestForCampaign.keySet(), not(hasItem("EshowsVideoType")));
    }

    private void setEshowsVideoRate(long cid, @Nullable BigDecimal rate) {
        CampOptionsRecord co = jooqDbSteps.campaignsSteps().getCampOptionsById(cid);
        co.setEshowsVideoRate(rate);
        jooqDbSteps.campaignsSteps().updateCampOptions(co);
    }

    private void setEshowsBannerRate(long cid, @Nullable BigDecimal rate) {
        CampOptionsRecord co = jooqDbSteps.campaignsSteps().getCampOptionsById(cid);
        co.setEshowsBannerRate(rate);
        jooqDbSteps.campaignsSteps().updateCampOptions(co);
    }

    private void setEshowsVideoType(long cid, @Nullable String type) {
        CampOptionsRecord co = jooqDbSteps.campaignsSteps().getCampOptionsById(cid);
        co.setEshowsVideoType(type);
        jooqDbSteps.campaignsSteps().updateCampOptions(co);
    }
}
