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

import java.util.List;

import com.yandex.direct.api.v5.bidmodifiers.BidModifierGetItem;
import com.yandex.direct.api.v5.general.AgeRangeEnum;
import com.yandex.direct.api.v5.general.GenderEnum;
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.api.bidmodifiers.BidModifiersFeatures;
import ru.yandex.autotests.direct.api.bidmodifiers.BidModifiersLogins;
import ru.yandex.autotests.direct.utils.model.RegionIDValues;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.Action;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.BidModifierAddMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.BidModifierSetMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.DemographicsAdjustmentMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.RegionalAdjustmentMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.SetRequestMap;
import ru.yandex.autotests.directapi.model.api5.general.ExpectedResult;
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.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static ch.lambdaj.Lambda.extract;
import static ch.lambdaj.Lambda.on;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.hasSize;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by chicos on 07.08.15
 */
@Aqua.Test
@Features(BidModifiersFeatures.SET)
@Tag(TagDictionary.TRUNK)
@Description("Проверка позитивных сценариев модификации множественных корректировок ставок")
public class SetBidModifiersPositiveMultipleTest {
    private LogSteps log = LogSteps.getLogger(this.getClass());
    private static final String client = BidModifiersLogins.SINGLE_CLIENT_SET;

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

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

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

    private long groupID;
    private static Long campaignID;

    @BeforeClass
    public static void createCampaign() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        campaignID = api.userSteps.campaignSteps().addDefaultTextCampaign(client);
    }

    @Before
    @Step("Подготовка данных для теста")
    public void prepareGroup() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        groupID = api.userSteps.adGroupsSteps().addDefaultGroup(campaignID);
    }

    @Test
    @Description("Модификация корректировок ставок для группы разных типов в одном запросе")
    public void setBidModifiersDifferentTypeGroupTest() {
        log.info("Подготовим корректировки ставок разных типов");
        Integer conditionId = api.userSteps.retargetingSteps().addRandomRetargetingCondition(client);
        Long bmID1 = api.userSteps.bidModifiersSteps().addBidModifierRetargetingToGroup(conditionId.longValue(), groupID);
        Long bmID2 = api.userSteps.bidModifiersSteps().addBidModifierMobileToGroup(groupID);
        Long bmID3 = api.userSteps.bidModifiersSteps().addBidModifierDemographicsToGroup(groupID);
        Long bmID4 = api.userSteps.bidModifiersSteps().addBidModifierVideoToGroup(groupID);

        api.userSteps.bidModifiersSteps().shouldGetResultOn(
                Action.SET,
                new SetRequestMap().withBidModifiers(
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID1),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID2),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID3),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID4)),
                ExpectedResult.success(bmID1),
                ExpectedResult.success(bmID2),
                ExpectedResult.success(bmID3),
                ExpectedResult.success(bmID4));
    }

    @Test
    @Description("Модификация корректировок ставок для камапании разных типов в одном запросе")
    public void setBidModifiersDifferentTypeCampaignTest() {
        log.info("Подготовим корректировки ставок разных типов");
        Integer conditionId = api.userSteps.retargetingSteps().addRandomRetargetingCondition(client);
        Long bmID1 = api.userSteps.bidModifiersSteps().addBidModifierRetargetingToCampaign(conditionId.longValue(), campaignID.intValue());
        Long bmID2 = api.userSteps.bidModifiersSteps().addBidModifierMobileToCampaign(campaignID);
        Long bmID3 = api.userSteps.bidModifiersSteps().addBidModifierDemographicsToCampaign(campaignID.intValue());
        Long bmID4 = api.userSteps.bidModifiersSteps().addBidModifierRegionalToCampaign(campaignID);
        Long bmID5 = api.userSteps.bidModifiersSteps().addBidModifierVideoToCampaign(campaignID);
        Long bmID6 = api.userSteps.bidModifiersSteps().addBidModifierSerpLayoutToCampaign(campaignID);

        api.userSteps.bidModifiersSteps().shouldGetResultOn(
                Action.SET,
                new SetRequestMap().withBidModifiers(
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID1),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID2),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID3),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID4),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID5),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmID6)),
                ExpectedResult.success(bmID1),
                ExpectedResult.success(bmID2),
                ExpectedResult.success(bmID3),
                ExpectedResult.success(bmID4),
                ExpectedResult.success(bmID5),
                ExpectedResult.success(bmID6));
    }

    @Test
    @Description("Модификация нескольких демографических корректировок ставок")
    public void setBidModifiersSameDemographicTypeTest() {
        log.info("Подготовим демографические корректировки ставок");
        List<Long> bmIDs = api.userSteps.bidModifiersSteps().bidModifiersAdd(new BidModifierAddMap()
                .withDemographicsAdjustment(new DemographicsAdjustmentMap()
                                .withGender(GenderEnum.GENDER_FEMALE)
                                .withAge(AgeRangeEnum.AGE_18_24)
                                .withDefaultBidModifier(),
                        new DemographicsAdjustmentMap()
                                .withGender(GenderEnum.GENDER_MALE)
                                .withAge(AgeRangeEnum.AGE_25_34)
                                .withDefaultBidModifier())
                .withAdGroupId(groupID));
        assumeThat("созданы корректировки ставок", bmIDs, hasSize(2));

        api.userSteps.bidModifiersSteps().shouldGetResultOn(
                Action.SET,
                new SetRequestMap().withBidModifiers(
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmIDs.get(0)),
                        new BidModifierSetMap()
                                .defaultBidModifier()
                                .withId(bmIDs.get(1))),
                ExpectedResult.success(bmIDs.get(0)),
                ExpectedResult.success(bmIDs.get(1)));
        List<BidModifierGetItem> bms = api.userSteps.bidModifiersSteps().bidModifiersGetById(bmIDs.get(0), bmIDs.get(1));
        assumeThat("получили корректировки ставок", bms, hasSize(2));
        List<Integer> modifierValues = extract(bms, on(BidModifierGetItem.class).getDemographicsAdjustment().getBidModifier());
        assertThat("корректировки ставок модифицированы",
                modifierValues, everyItem(equalTo(BidModifierSetMap.DEFAULT_BID_MODIFIER)));
    }

    @Test
    @Description("Модификация нескольких корректировок ставок по региону")
    public void setBidModifiersSameRegionalTypeTest() {
        log.info("Подготовим демографические корректировки ставок по региону");
        List<Long> bmIDs = api.userSteps.bidModifiersSteps().bidModifiersAdd(new BidModifierAddMap()
                .withRegionalAdjustment(new RegionalAdjustmentMap()
                                .withRegionId(RegionIDValues.MOSCOW.getId())
                                .withDefaultBidModifier(),
                        new RegionalAdjustmentMap()
                                .withRegionId(RegionIDValues.SEVASTOPOL.getId())
                                .withDefaultBidModifier())
                .withCampaignId(campaignID));
        assumeThat("созданы корректировки ставок", bmIDs, hasSize(2));

        api.userSteps.bidModifiersSteps().shouldGetResultOn(
                Action.SET,
                new SetRequestMap().withBidModifiers(
                        new BidModifierSetMap()
                                .withBidModifier(BidModifierSetMap.DEFAULT_BID_MODIFIER/2)
                                .withId(bmIDs.get(0)),
                        new BidModifierSetMap()
                                .withBidModifier(BidModifierSetMap.DEFAULT_BID_MODIFIER/2)
                                .withId(bmIDs.get(1))),
                ExpectedResult.success(bmIDs.get(0)),
                ExpectedResult.success(bmIDs.get(1)));
        List<BidModifierGetItem> bms = api.userSteps.bidModifiersSteps().bidModifiersGetById(bmIDs.get(0), bmIDs.get(1));
        assumeThat("получили корректировки ставок", bms, hasSize(2));
        List<Integer> modifierValues = extract(bms, on(BidModifierGetItem.class).getRegionalAdjustment().getBidModifier());
        assertThat("корректировки ставок модифицированы",
                modifierValues, everyItem(equalTo(BidModifierSetMap.DEFAULT_BID_MODIFIER/2)));
    }
}
