package ru.yandex.autotests.direct.api.keywordbids.set;


import java.util.Arrays;
import java.util.Collections;
import ru.yandex.qatools.allure.annotations.TestCaseId;

import com.yandex.direct.api.v5.general.PriorityEnum;
import com.yandex.direct.api.v5.keywordbids.GetResponse;
import com.yandex.direct.api.v5.keywordbids.KeywordBidFieldEnum;
import com.yandex.direct.api.v5.keywordbids.KeywordBidNetworkFieldEnum;
import com.yandex.direct.api.v5.keywordbids.KeywordBidSearchFieldEnum;
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.bids.BidsLogins;
import ru.yandex.autotests.direct.api.keywordbids.KeywordBidsFeatures;
import ru.yandex.autotests.direct.utils.money.Currency;
import ru.yandex.autotests.direct.utils.money.MoneyCurrency;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.ProtocolType;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.campaigns.TextCampaignNetworkStrategyAddMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.TextCampaignSearchStrategyAddMap;
import ru.yandex.autotests.directapi.model.api5.keywordbids.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.keywordbids.KeywordBidExpectedResult;
import ru.yandex.autotests.directapi.model.api5.keywordbids.KeywordBidsGetItemMap;
import ru.yandex.autotests.directapi.model.api5.keywordbids.KeywordBidsSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.keywordbids.KeywordBidsSetItemMap;
import ru.yandex.autotests.directapi.model.api5.keywordbids.SetRequestMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.irt.testutils.allure.LogSteps;
import ru.yandex.qatools.Tag;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.directapi.matchers.beans.version5.BeanDifferMatcherV5.beanDifferV5;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

@Aqua.Test
@Features(KeywordBidsFeatures.SET)
@Tag(TagDictionary.TRUNK)
public class SetPositiveTest {

    private static final Long MIN_BID = MoneyCurrency.get(Currency.RUB).getLongMinPrice().longValue();
    private static final Long BID1 = MIN_BID * 2L;
    private static final Long BID2 = BID1 * 2L;
    private static final Long BID3 = BID2 * 2L;
    private static final Long BID4 = BID3 * 2L;
    private static final Long BID5 = BID4 * 2L;
    private static final Long BID6 = BID5 * 2L;
    private static final Long BID7 = BID6 * 2L;
    private static final Long BID8 = BID7 * 2L;

    private static Long adGroupId1;
    private static Long adGroupId2;
    private static long keywordId1;
    private static long keywordId2;
    private static Long autotargetingId;
    private static Long campaignID;
    private static Long campaignIDWithAutoStrategy;
    private static long keywordId22;
    private static Long autotargetingId2;
    protected LogSteps log = LogSteps.getLogger(this.getClass());
    private static String login = BidsLogins.SUPER;

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

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

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


    @BeforeClass
    @Step("Подготовка данных для теста")
    public static void readBanner() {
        api.userSteps.clientFakeSteps().setAPIUnits(BidsLogins.BIDS_CLIENT, 12000000);
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(BidsLogins.BIDS_CLIENT);
        api.userSteps.clientFakeSteps().enableAPI(BidsLogins.BIDS_CLIENT);
        campaignID = api.as(BidsLogins.BIDS_CLIENT).userSteps.campaignSteps().addDefaultTextCampaignWithStrategies(
                new TextCampaignSearchStrategyAddMap().defaultHighestPosition(),
                new TextCampaignNetworkStrategyAddMap().defaultMaximumCoverage()
        );
        adGroupId1 = api.userSteps.adGroupsSteps().addDefaultGroup(campaignID);
        api.userSteps.adsSteps().addDefaultTextAd(adGroupId1);
        keywordId1 = api.userSteps.keywordsSteps().addDefaultKeyword(adGroupId1);
        autotargetingId = api.userSteps.keywordsSteps().addAutotargeting(adGroupId1);
        adGroupId2 = api.userSteps.adGroupsSteps().addDefaultGroup(campaignID);
        api.userSteps.adsSteps().addDefaultTextAd(adGroupId2);
        keywordId2 = api.userSteps.keywordsSteps().addDefaultKeyword(adGroupId2);

        campaignIDWithAutoStrategy = api.userSteps.campaignSteps().addDefaultTextCampaignWithStrategies(
                new TextCampaignSearchStrategyAddMap().defaultWbMaximumClicks(Currency.RUB),
                new TextCampaignNetworkStrategyAddMap().defaultNetworkDefault()
        );
        Long adGroupId3 = api.userSteps.adGroupsSteps().addDefaultGroup(campaignIDWithAutoStrategy);
        api.userSteps.adsSteps().addDefaultTextAd(adGroupId3);
        keywordId22 = api.userSteps.keywordsSteps().addDefaultKeyword(adGroupId3);
        autotargetingId2 = api.userSteps.keywordsSteps().addDefaultKeyword(adGroupId3);

    }

    @Test
    @TestCaseId("2907")
    public void setOnlyBid() {
        //testplan: string № 51
        //https://st.yandex-team.ru/DIRECT-33874
        api.userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap()
                        .withKeywordBids(
                                new KeywordBidsSetItemMap()
                                        .withKeywordId(keywordId1)
                                        .withSearchBid(BID1),
                                new KeywordBidsSetItemMap()
                                        .withKeywordId(autotargetingId)
                                        .withSearchBid(BID2)
                        ),
                KeywordBidExpectedResult.successWithKeywordId(),
                KeywordBidExpectedResult.successWithKeywordId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap().withSelectionCriteria(
                        new KeywordBidsSelectionCriteriaMap().withKeywordIds(keywordId1, autotargetingId)
                ).withFieldNames(KeywordBidFieldEnum.KEYWORD_ID).withSearchFieldNames(KeywordBidSearchFieldEnum.BID)
        );
        assertThat("получили правильные значения Bid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Arrays.asList(
                                new KeywordBidsGetItemMap().withKeywordId(keywordId1).withSearchBid(BID1).getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(autotargetingId).withSearchBid(BID2).getBean()
                        )
                )
        );
    }

    @Test
    @TestCaseId("2908")
    public void setOnlyContextBid() {
        api.userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap()
                        .withKeywordBids(
                                new KeywordBidsSetItemMap()
                                        .withKeywordId(keywordId1)
                                        .withNetworkBid(BID1),
                                new KeywordBidsSetItemMap()
                                        .withKeywordId(autotargetingId)
                                        .withNetworkBid(BID2)
                        ),
                KeywordBidExpectedResult.successWithKeywordId(),
                KeywordBidExpectedResult.successWithKeywordId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap().withSelectionCriteria(
                        new KeywordBidsSelectionCriteriaMap().withKeywordIds(keywordId1, autotargetingId)
                ).withFieldNames(KeywordBidFieldEnum.KEYWORD_ID).withNetworkFieldNames(KeywordBidNetworkFieldEnum.BID)
        );
        assertThat("получили правильные значения ContextBid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Arrays.asList(
                                new KeywordBidsGetItemMap().withKeywordId(keywordId1).withNetworkBid(BID1).getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(autotargetingId).withNetworkBid(BID2)
                                        .getBean()
                        )
                )
        );
    }

    @Test
    @TestCaseId("2909")
    public void setOnlyContextBidByCampaignId() {
        //testplan: string № 56, 49
        //https://st.yandex-team.ru/DIRECT-33874
        api.userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap()
                        .withKeywordBids(
                                new KeywordBidsSetItemMap()
                                        .withCampaignId(campaignID)
                                        .withNetworkBid(BID3)
                        ),
                KeywordBidExpectedResult.successWithCampaignId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap().withSelectionCriteria(
                        new KeywordBidsSelectionCriteriaMap().withCampaignIds(campaignID)
                ).withFieldNames(KeywordBidFieldEnum.KEYWORD_ID).withNetworkFieldNames(KeywordBidNetworkFieldEnum.BID)
        );
        assertThat("получили правильные значения ContextBid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Arrays.asList(
                                new KeywordBidsGetItemMap().withKeywordId(keywordId1).withNetworkBid(BID3).getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(autotargetingId).withNetworkBid(BID3)
                                        .getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(keywordId2).withNetworkBid(BID3).getBean()
                        )
                )
        );
    }


    @Test
    @TestCaseId("2910")
    public void setOneValidBidsWithCampaignId() {
        //testplan: string №38
        api.protocol(ProtocolType.SOAP).userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap().withKeywordBids(
                        new KeywordBidsSetItemMap()
                                .withCampaignId(campaignID)
                                .withSearchBid(BID3)
                                .withNetworkBid(BID4)
                ),
                new KeywordBidExpectedResult().successWithCampaignId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new KeywordBidsSelectionCriteriaMap().withCampaignIds(campaignID)
                        )
                        .withFieldNames(KeywordBidFieldEnum.KEYWORD_ID)
                        .withSearchFieldNames(KeywordBidSearchFieldEnum.BID)
                        .withNetworkFieldNames(KeywordBidNetworkFieldEnum.BID));
        assertThat("получили правильные значения Bid и ContextBid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Arrays.asList(
                                new KeywordBidsGetItemMap().withKeywordId(keywordId1).withSearchBid(BID3)
                                        .withNetworkBid(BID4)
                                        .getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(autotargetingId).withSearchBid(BID3)
                                        .withNetworkBid(BID4)
                                        .getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(keywordId2).withSearchBid(BID3)
                                        .withNetworkBid(BID4)
                                        .getBean()
                        )
                )
        );
    }

    @Test
    @TestCaseId("2911")
    public void setOneValidBidsWithAdGroupId() {
        //testplan: string №39
        api.protocol(ProtocolType.SOAP).userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap().withKeywordBids(
                        new KeywordBidsSetItemMap()
                                .withAdGroupId(adGroupId1)
                                .withSearchBid(BID5)
                                .withNetworkBid(BID6)),
                new KeywordBidExpectedResult().successWithAdGroupId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new KeywordBidsSelectionCriteriaMap().withAdGroupIds(adGroupId1)
                        ).withFieldNames(KeywordBidFieldEnum.KEYWORD_ID)
                        .withSearchFieldNames(KeywordBidSearchFieldEnum.BID)
                        .withNetworkFieldNames(KeywordBidNetworkFieldEnum.BID)
        );
        assertThat("получили правильные значения Bid и ContextBid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Arrays.asList(
                                new KeywordBidsGetItemMap().withKeywordId(keywordId1).withSearchBid(BID5)
                                        .withNetworkBid(BID6)
                                        .getBean(),
                                new KeywordBidsGetItemMap().withKeywordId(autotargetingId).withSearchBid(BID5)
                                        .withNetworkBid(BID6)
                                        .getBean()
                        )
                )
        );
    }

    @Test
    @TestCaseId("2912")
    public void setOneValidBidsWithKeywordId() {
        //testplan: string №30 № 40
        api.protocol(ProtocolType.SOAP).userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap().withKeywordBids(
                        new KeywordBidsSetItemMap()
                                .withKeywordId(keywordId2)
                                .withSearchBid(BID7)
                                .withNetworkBid(BID8)
                ),
                new KeywordBidExpectedResult().successWithKeywordId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new KeywordBidsSelectionCriteriaMap().withKeywordIds(keywordId2)
                        ).withFieldNames(KeywordBidFieldEnum.KEYWORD_ID)
                        .withSearchFieldNames(KeywordBidSearchFieldEnum.BID)
                        .withNetworkFieldNames(KeywordBidNetworkFieldEnum.BID)
        );
        assertThat("получили правильные значения Bid и ContextBid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Collections.singletonList(
                                new KeywordBidsGetItemMap().withKeywordId(keywordId2).withSearchBid(BID7)
                                        .withNetworkBid(BID8)
                                        .getBean()
                        )
                )
        );
    }

    @Test
    @TestCaseId("2913")
    public void setOneValidBidsWithAutotargetingId() {
        //testplan: string №30 № 40
        api.protocol(ProtocolType.SOAP).userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap().withKeywordBids(
                        new KeywordBidsSetItemMap()
                                .withKeywordId(autotargetingId)
                                .withSearchBid(BID8)
                                .withNetworkBid(BID7)
                ),
                new KeywordBidExpectedResult().successWithKeywordId()
        );
        GetResponse getResponse = api.userSteps.keywordBidsSteps().keywordBidsGet(
                new GetRequestMap().withNetworkFieldNames(KeywordBidNetworkFieldEnum.BID)
                        .withSearchFieldNames(KeywordBidSearchFieldEnum.BID)
                        .withFieldNames(KeywordBidFieldEnum.KEYWORD_ID)
                        .withSelectionCriteria(new KeywordBidsSelectionCriteriaMap().withKeywordIds(autotargetingId))

        );
        assertThat("получили правильные значения Bid и ContextBid",
                getResponse.getKeywordBids(),
                beanDifferV5(
                        Arrays.asList(
                                new KeywordBidsGetItemMap().withKeywordId(autotargetingId).withSearchBid(BID8)
                                        .withNetworkBid(BID7)
                                        .getBean()
                        )
                )
        );
    }

    @Test
    @TestCaseId("2914")
    public void setSomeValidWithDifferentFieldsBids() {
        //testplan: string №30
        // https://st.yandex-team.ru/DIRECT-35879
        api.userSteps.keywordBidsSteps().shouldGetKeywordBidResultOnSet(
                new SetRequestMap().withKeywordBids(
                        new KeywordBidsSetItemMap()
                                .withKeywordId(keywordId1)
                                .withNetworkBid(BID7),
                        new KeywordBidsSetItemMap()
                                .withKeywordId(autotargetingId)
                                .withSearchBid(BID8),
                        new KeywordBidsSetItemMap()
                                .withKeywordId(keywordId22)
                                .withStrategyPriority(PriorityEnum.HIGH),
                        new KeywordBidsSetItemMap()
                                .withKeywordId(autotargetingId2)
                                .withStrategyPriority(PriorityEnum.HIGH)
                ),
                new KeywordBidExpectedResult().successWithKeywordId(),
                new KeywordBidExpectedResult().successWithKeywordId(),
                new KeywordBidExpectedResult().successWithKeywordId(),
                new KeywordBidExpectedResult().successWithKeywordId()
        );
    }

}
