package ru.yandex.autotests.directapi.dynamictextadtargets.setbids;

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

import com.yandex.direct.api.v5.dynamictextadtargets.GetResponse;
import com.yandex.direct.api.v5.dynamictextadtargets.StringConditionOperatorEnum;
import com.yandex.direct.api.v5.dynamictextadtargets.WebpageConditionOperandEnum;
import com.yandex.direct.api.v5.dynamictextadtargets.WebpageFieldEnum;
import com.yandex.direct.api.v5.dynamictextadtargets.WebpageGetItem;
import com.yandex.direct.api.v5.general.PriorityEnum;
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.utils.money.Currency;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.dynamictextadtargets.DynamicTextAdTargetsFeatures;
import ru.yandex.autotests.directapi.dynamictextadtargets.DynamicTextAdTargetsLogins;
import ru.yandex.autotests.directapi.matchers.beandiffer2.Api5CompareStrategies;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.campaigns.CampaignAddItemMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.DynamicTextCampaignAddItemMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.DynamicTextCampaignNetworkStrategyAddMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.DynamicTextCampaignSearchStrategyAddMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.DynamicTextCampaignStrategyAddMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.SetBidsItemMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.SetBidsRequestMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.WebpageAddItemMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.WebpageConditionMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.WebpageGetItemMap;
import ru.yandex.autotests.directapi.model.api5.dynamictextadtargets.WebpagesSelectionCriteriaMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.irt.testutils.beandiffer2.comparestrategy.CompareStrategy;
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.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.beandiffer2.BeanDifferMatcher.beanDiffer;

/**
 * Created by semkagtn on 26.11.15.
 * https://st.yandex-team.ru/TESTIRT-7700
 */
@Aqua.Test
@Issue("https://st.yandex-team.ru/DIRECT-43826")
@Features(DynamicTextAdTargetsFeatures.SET_BIDS)
@Description("Установка значения Bid методом SetBids")
public class SetBidsStrategyPriorityTest {

    private static final String LOGIN = DynamicTextAdTargetsLogins.SINGLE_CLIENT;

    private static final PriorityEnum OLD_PRIORITY = PriorityEnum.NORMAL;
    private static final PriorityEnum NEW_PRIORITY = PriorityEnum.HIGH;

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

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

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

    private static int shard;
    private static int uid;

    @BeforeClass
    public static void prepareStaticData() {
        shard = api.userSteps.clientFakeSteps().getUserShard(LOGIN);
        uid = Integer.parseInt(User.get(LOGIN).getPassportUID());
    }

    private Long campaignId;

    private Long firstAdGroupId;
    private Long firstWebpageId1;
    private Long firstWebpageId2;

    private Long secondAdGroupId;
    private Long secondWebpageId;


    private Long campaignIdElse;

    private Long adGroupIdElse;
    private Long webpageIdElse;

    @Before
    @Step("Подготовка данных для теста")
    public void createWebpages() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(LOGIN);

        campaignId = api.userSteps.campaignSteps().addCampaign(new CampaignAddItemMap()
                .defaultCampaignAddItem()
                .withDynamicTextCampaign(new DynamicTextCampaignAddItemMap()
                        .defaultDynamicTextCampaign()
                        .withBiddingStrategy(new DynamicTextCampaignStrategyAddMap()
                                .withSearch(new DynamicTextCampaignSearchStrategyAddMap().defaultWbMaximumClicks(Currency.RUB))
                                .withNetwork(new DynamicTextCampaignNetworkStrategyAddMap().defaultServingOff())
                        )));
        firstAdGroupId = api.userSteps.adGroupsSteps().addDefaultGroupDynamic(campaignId);
        secondAdGroupId = api.userSteps.adGroupsSteps().addDefaultGroupDynamic(campaignId);

        campaignIdElse = api.userSteps.campaignSteps().addCampaign(new CampaignAddItemMap()
                .defaultCampaignAddItem()
                .withDynamicTextCampaign(new DynamicTextCampaignAddItemMap()
                        .defaultDynamicTextCampaign()
                        .withBiddingStrategy(new DynamicTextCampaignStrategyAddMap()
                                .withSearch(new DynamicTextCampaignSearchStrategyAddMap().defaultWbMaximumClicks(Currency.RUB))
                                .withNetwork(new DynamicTextCampaignNetworkStrategyAddMap().defaultServingOff())
                        )));
        adGroupIdElse = api.userSteps.adGroupsSteps().addDefaultGroupDynamic(campaignIdElse);

        List<Long> webpageIds = api.userSteps.dynamicTextAdTargetsSteps().addWebpages(
                new WebpageAddItemMap()
                        .withAdGroupId(firstAdGroupId)
                        .withName("Name1")
                        .withConditions(new WebpageConditionMap()
                                .withOperand(WebpageConditionOperandEnum.PAGE_TITLE)
                                .withOperator(StringConditionOperatorEnum.CONTAINS_ANY)
                                .withArguments("arg1"))
                        .withStrategyPriority(OLD_PRIORITY),
                new WebpageAddItemMap()
                        .withAdGroupId(firstAdGroupId)
                        .withName("Name2")
                        .withConditions(new WebpageConditionMap()
                                .withOperand(WebpageConditionOperandEnum.PAGE_CONTENT)
                                .withOperator(StringConditionOperatorEnum.CONTAINS_ANY)
                                .withArguments("arg2"))
                        .withStrategyPriority(OLD_PRIORITY),
                new WebpageAddItemMap()
                        .withAdGroupId(secondAdGroupId)
                        .withName("Name3")
                        .withConditions(new WebpageConditionMap()
                                .withOperand(WebpageConditionOperandEnum.PAGE_CONTENT)
                                .withOperator(StringConditionOperatorEnum.CONTAINS_ANY)
                                .withArguments("arg3"))
                        .withStrategyPriority(OLD_PRIORITY),
                new WebpageAddItemMap()
                        .withAdGroupId(adGroupIdElse)
                        .withName("Name4")
                        .withConditions(new WebpageConditionMap()
                                .withOperand(WebpageConditionOperandEnum.PAGE_CONTENT)
                                .withOperator(StringConditionOperatorEnum.CONTAINS_ANY)
                                .withArguments("arg4"))
                        .withStrategyPriority(OLD_PRIORITY));
        firstWebpageId1 = webpageIds.get(0);
        firstWebpageId2 = webpageIds.get(1);
        secondWebpageId = webpageIds.get(2);
        webpageIdElse = webpageIds.get(3);
    }

    @Test
    @Description("Идентификатор webpage в запросе")
    public void setBidById() {
        api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsSetBids(new SetBidsRequestMap()
                .withBids(new SetBidsItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY)));

        GetResponse actualResponse = api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsGet(new GetRequestMap()
                .withFieldNames(WebpageFieldEnum.ID, WebpageFieldEnum.STRATEGY_PRIORITY)
                .withSelectionCriteria(new WebpagesSelectionCriteriaMap()
                        .withCampaignIds(campaignId, campaignIdElse)));
        List<WebpageGetItem> actualResult = actualResponse.getWebpages();
        actualResult.sort((x, y) -> x.getId().compareTo(y.getId()));

        List<WebpageGetItem> expectedResult = Arrays.asList(
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId2)
                        .withStrategyPriority(OLD_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(OLD_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(webpageIdElse)
                        .withStrategyPriority(OLD_PRIORITY).getBean());

        CompareStrategy strategy = Api5CompareStrategies.onlyExpectedFields();
        assertThat("результат соответствует ожидаемому", actualResult, beanDiffer(expectedResult)
                .useCompareStrategy(strategy));
    }

    @Test
    @Description("Два идентификатора webpage в запросе")
    public void setBidsByTwoIds() {
        api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsSetBids(new SetBidsRequestMap().withBids(
                new SetBidsItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY),
                new SetBidsItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(NEW_PRIORITY)));

        GetResponse actualResponse = api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsGet(new GetRequestMap()
                .withFieldNames(WebpageFieldEnum.ID, WebpageFieldEnum.STRATEGY_PRIORITY)
                .withSelectionCriteria(new WebpagesSelectionCriteriaMap()
                        .withCampaignIds(campaignId, campaignIdElse)));
        List<WebpageGetItem> actualResult = actualResponse.getWebpages();
        actualResult.sort((x, y) -> x.getId().compareTo(y.getId()));

        List<WebpageGetItem> expectedResult = Arrays.asList(
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId2)
                        .withStrategyPriority(OLD_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(webpageIdElse)
                        .withStrategyPriority(OLD_PRIORITY).getBean());

        CompareStrategy strategy = Api5CompareStrategies.onlyExpectedFields();
        assertThat("результат соответствует ожидаемому", actualResult, beanDiffer(expectedResult)
                .useCompareStrategy(strategy));
    }

    @Test
    @Description("Идентификатор группы в запросе")
    public void setBidsByAdGroupId() {
        api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsSetBids(new SetBidsRequestMap()
                .withBids(new SetBidsItemMap()
                        .withAdGroupId(firstAdGroupId)
                        .withStrategyPriority(NEW_PRIORITY)));

        GetResponse actualResponse = api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsGet(new GetRequestMap()
                .withFieldNames(WebpageFieldEnum.ID, WebpageFieldEnum.STRATEGY_PRIORITY)
                .withSelectionCriteria(new WebpagesSelectionCriteriaMap()
                        .withCampaignIds(campaignId, campaignIdElse)));
        List<WebpageGetItem> actualResult = actualResponse.getWebpages();
        actualResult.sort((x, y) -> x.getId().compareTo(y.getId()));

        List<WebpageGetItem> expectedResult = Arrays.asList(
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId2)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(OLD_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(webpageIdElse)
                        .withStrategyPriority(OLD_PRIORITY).getBean());

        CompareStrategy strategy = Api5CompareStrategies.onlyExpectedFields();
        assertThat("результат соответствует ожидаемому", actualResult, beanDiffer(expectedResult)
                .useCompareStrategy(strategy));
    }

    @Test
    @Description("Два идентификатора группы в запросе")
    public void setBidsByTwoAdGroupIds() {
        api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsSetBids(new SetBidsRequestMap().withBids(
                new SetBidsItemMap()
                        .withAdGroupId(firstAdGroupId)
                        .withStrategyPriority(NEW_PRIORITY),
                new SetBidsItemMap()
                        .withAdGroupId(adGroupIdElse)
                        .withStrategyPriority(NEW_PRIORITY)));

        GetResponse actualResponse = api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsGet(new GetRequestMap()
                .withFieldNames(WebpageFieldEnum.ID, WebpageFieldEnum.STRATEGY_PRIORITY)
                .withSelectionCriteria(new WebpagesSelectionCriteriaMap()
                        .withCampaignIds(campaignId, campaignIdElse)));
        List<WebpageGetItem> actualResult = actualResponse.getWebpages();
        actualResult.sort((x, y) -> x.getId().compareTo(y.getId()));

        List<WebpageGetItem> expectedResult = Arrays.asList(
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId2)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(OLD_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(webpageIdElse)
                        .withStrategyPriority(NEW_PRIORITY).getBean());

        CompareStrategy strategy = Api5CompareStrategies.onlyExpectedFields();
        assertThat("результат соответствует ожидаемому", actualResult, beanDiffer(expectedResult)
                .useCompareStrategy(strategy));
    }

    @Test
    @Description("Идентификатор кампании в запросе")
    public void setBidsByCampaignId() {
        api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsSetBids(new SetBidsRequestMap()
                .withBids(new SetBidsItemMap()
                        .withCampaignId(campaignId)
                        .withStrategyPriority(NEW_PRIORITY)));

        GetResponse actualResponse = api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsGet(new GetRequestMap()
                .withFieldNames(WebpageFieldEnum.ID, WebpageFieldEnum.STRATEGY_PRIORITY)
                .withSelectionCriteria(new WebpagesSelectionCriteriaMap()
                        .withCampaignIds(campaignId, campaignIdElse)));
        List<WebpageGetItem> actualResult = actualResponse.getWebpages();
        actualResult.sort((x, y) -> x.getId().compareTo(y.getId()));

        List<WebpageGetItem> expectedResult = Arrays.asList(
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId2)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(webpageIdElse)
                        .withStrategyPriority(OLD_PRIORITY).getBean());

        CompareStrategy strategy = Api5CompareStrategies.onlyExpectedFields();
        assertThat("результат соответствует ожидаемому", actualResult, beanDiffer(expectedResult)
                .useCompareStrategy(strategy));
    }

    @Test
    @Description("Два идентификатора кампаний в запросе")
    public void setBidsByTwoCampaignIds() {
        api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsSetBids(new SetBidsRequestMap().withBids(
                new SetBidsItemMap()
                        .withCampaignId(campaignId)
                        .withStrategyPriority(NEW_PRIORITY),
                new SetBidsItemMap()
                        .withCampaignId(campaignIdElse)
                        .withStrategyPriority(NEW_PRIORITY)));

        GetResponse actualResponse = api.userSteps.dynamicTextAdTargetsSteps().dynamicTextAdTargetsGet(new GetRequestMap()
                .withFieldNames(WebpageFieldEnum.ID, WebpageFieldEnum.STRATEGY_PRIORITY)
                .withSelectionCriteria(new WebpagesSelectionCriteriaMap()
                        .withCampaignIds(campaignId, campaignIdElse)));
        List<WebpageGetItem> actualResult = actualResponse.getWebpages();
        actualResult.sort((x, y) -> x.getId().compareTo(y.getId()));

        List<WebpageGetItem> expectedResult = Arrays.asList(
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId1)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(firstWebpageId2)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(secondWebpageId)
                        .withStrategyPriority(NEW_PRIORITY).getBean(),
                (WebpageGetItem) new WebpageGetItemMap()
                        .withId(webpageIdElse)
                        .withStrategyPriority(NEW_PRIORITY).getBean());

        CompareStrategy strategy = Api5CompareStrategies.onlyExpectedFields();
        assertThat("результат соответствует ожидаемому", actualResult, beanDiffer(expectedResult)
                .useCompareStrategy(strategy));
    }
}
