package ru.yandex.autotests.directintapi.bstransport.main.dynbanner.parameters.bannerland;

import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;
import org.junit.After;
import org.junit.Before;
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.db.models.jooq.ppc.enums.BannersBannerType;
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.CampaignsType;
import ru.yandex.autotests.directapi.darkside.model.HrefMacrosDMO;
import ru.yandex.autotests.directapi.darkside.model.HrefOpeningParams;
import ru.yandex.autotests.directapi.darkside.model.RunBsTransportScriptResponse;
import ru.yandex.autotests.directapi.darkside.model.bslogs.UpdateInfo;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Banner;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.BannerLandDataDynamicFeed;
import ru.yandex.autotests.directapi.darkside.steps.TransportSteps;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.campaigns.CampaignAddItemMap;
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.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.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.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;

@Aqua.Test
@Tag(TagDictionary.TRUNK)
@Tag(TagDictionary.RELEASE)
@Issue("https://st.yandex-team.ru/DIRECT-158191")
@Title("Транспорт: проверка отправки в БК BannerLandData для дин. баннера. по фиду. Поле SubstituteURLParams")
@Stories(StoriesNames.DYN_BANNER_PARAMS_BANNERLAND)
@Features(FeatureNames.DYN_BANNERS)
public class BsTransportOfTGOFeedDynamicBannerLandDataSubstituteURLParamsTest {

    private static final String CAMPAIGN_NAME = "Новая кампания";
    private static final String URL_PARAMS_CAMPAIGN_NAME = "%D0%9D%D0%BE%D0%B2%D0%B0%D1%8F%20%D0%BA%D0%B0%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F";
    private static final String URL_PARAMS_CAMPAIGN_NAME_LAT = "Novaya_kampaniya";
    private static final String LOGIN = Logins.LOGIN_TRANSPORT;

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

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

    private static TransportSteps transportSteps = api.userSteps.getDarkSideSteps().getTransportSteps();

    private static int shard;

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

    private Banner banner;
    private Long cid;
    private Long pid;
    private long feedId;

    @BeforeClass
    public static void beforeClass() {
        shard = api.userSteps.clientFakeSteps().getUserShard(LOGIN);
    }

    @Step("Подготовка данных для теста")
    @Before
    public void before() {
        cid = api.userSteps.campaignSteps().addCampaign(
                new CampaignAddItemMap().defaultCampaignAddItem().withDefaultTextCampaign()
                        .withName(CAMPAIGN_NAME)
        );
        api.userSteps.campaignFakeSteps().makeNewCampaignReadyForSendingToBS(cid);
        pid = api.userSteps.adGroupsSteps().addDefaultGroup(cid);
        Long bid = api.userSteps.adsSteps().addDefaultTextAd(pid);
        api.userSteps.getDirectJooqDbSteps().useShard(shard).bannersSteps()
                .setBannersBannerType(bid, BannersBannerType.dynamic);

        Long keywordId = api.userSteps.keywordsSteps().addDefaultKeyword(pid);
        feedId = api.userSteps.getDirectJooqDbSteps().useShard(shard).feedsSteps()
                .createDefaultFeed(User.get(LOGIN).getClientID());
        api.userSteps.getDirectJooqDbSteps().useShard(shard).adGroupsSteps()
                .setAdgroupsTextFeedIdAndFilter(pid, feedId, "{}");

        api.userSteps.campaignFakeSteps().makeNewCampaignReadyForSendingToBS(cid);
        api.userSteps.groupFakeSteps().makeGroupFullyModerated(pid);
        api.userSteps.bannersFakeSteps().makeBannerFullyModerated(bid);
        api.userSteps.phrasesFakeSteps().makeKeywordModerated(keywordId);

        RunBsTransportScriptResponse resp = transportSteps.sendNewCampaign(shard, cid);
        banner = transportSteps.getClientDataRequestCampaign(resp, 0, cid).getContext(pid).getBanner(bid);
    }

    @Test
    @Title("Отправка в БК BannerLandData для дин. баннера в тго группе")
    public void testBannerLandData() {
        assumeThat("в БК отправлен баннер", banner, notNullValue());
        assumeThat("UpdateInfo отправленного баннера " + UpdateInfo.UPDATE
                , banner.getUpdateInfo(), equalTo(UpdateInfo.UPDATE.value()));
        assumeThat("в БК отпралено поле BannerLandData", banner.getBannerLandData(), notNullValue());
        BannerLandDataDynamicFeed bannerLandData = new Gson().fromJson(banner.getBannerLandData()
                , BannerLandDataDynamicFeed.class);
        assumeThat("в БК на уровне BANNER отправилось поле BannerLandData с SubstituteURLParams"
                , bannerLandData.getSubstituteURLParams()
                , notNullValue());
        Map<String, String> expectedSubstituteURLParams = new HashMap<>();
        for (HrefMacrosDMO hrefMacrosDMO : HrefMacrosDMO.values()) {
            expectedSubstituteURLParams
                    .put("{" + hrefMacrosDMO.getValue() + "}", "{" + hrefMacrosDMO.getMacros() + "}");
        }
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.ADGROUP_ID.getParamName() + "}", pid.toString());
        expectedSubstituteURLParams.put("{" +HrefOpeningParams.ADGROUPID.getParamName() + "}", pid.toString());
        expectedSubstituteURLParams.put("{" +HrefOpeningParams.CAMPAIGN_TYPE.getParamName() + "}", CampaignsType.TEXT.type());
        expectedSubstituteURLParams.put("{" +HrefOpeningParams.CAMPAIGNTYPE.getParamName() + "}", CampaignsType.TEXT.type());
        expectedSubstituteURLParams.put("{" +HrefOpeningParams.CAMPAIGN_ID.getParamName() + "}", cid.toString());
        expectedSubstituteURLParams.put("{" +HrefOpeningParams.CAMPAIGNID.getParamName() + "}", cid.toString());
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGN_NAME.getParamName() + "}",
                URL_PARAMS_CAMPAIGN_NAME);
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGNNAME.getParamName() + "}",
                URL_PARAMS_CAMPAIGN_NAME);
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGN_NAME_LAT.getParamName() + "}",
                URL_PARAMS_CAMPAIGN_NAME_LAT);
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGNNAMELAT.getParamName() + "}",
                URL_PARAMS_CAMPAIGN_NAME_LAT);
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGN_CURRENCY.getParamName() + "}", "RUB");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGNCURRENCY.getParamName() + "}", "RUB");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGN_CURRENCY_CODE.getParamName() + "}", "643");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGNCURRENCYCODE.getParamName() + "}", "643");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGN_COST_TYPE.getParamName() + "}","");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGNCOSTTYPE.getParamName() + "}", "");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGN_COST.getParamName() + "}", "");
        expectedSubstituteURLParams.put("{" + HrefOpeningParams.CAMPAIGNCOST.getParamName() + "}", "");
        assertThat("в БК отправились SubstituteURLParams с правильными значениями "
                , bannerLandData.getSubstituteURLParams(), beanDiffer(expectedSubstituteURLParams));
    }

    @After
    public void clearFeed() {
        if (feedId > 0) {
            api.userSteps.getDirectJooqDbSteps().useShard(shard).feedsSteps().deleteFeedAndAllLinksByFeedId(feedId);
        }
    }
}
