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

import java.util.List;

import com.yandex.direct.api.v5.bidmodifiers.BidModifierFieldEnum;
import com.yandex.direct.api.v5.bidmodifiers.BidModifierGetItem;
import com.yandex.direct.api.v5.bidmodifiers.BidModifierTypeEnum;
import com.yandex.direct.api.v5.bidmodifiers.DesktopAdjustmentFieldEnum;
import com.yandex.direct.api.v5.bidmodifiers.MobileAdjustmentFieldEnum;
import com.yandex.direct.api.v5.bidmodifiers.OperatingSystemTypeEnum;
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.api.bidmodifiers.get.desktop.GetBidModifiersFieldNamesDesktopTest;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.BidModifierAddMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.BidModifiersSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.DesktopAdjustmentGetMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.DesktopAdjustmentMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.MobileAdjustmentGetMap;
import ru.yandex.autotests.directapi.model.api5.bidmodifiers.MobileAdjustmentMap;
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.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static ru.yandex.autotests.directapi.matchers.beandiffer2.BeanDifferMatcherV5.beanDifferV5;
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
@Features(BidModifiersFeatures.GET)
@Description("Проверка выдачи при использовании фильтра по DesktopAdjustmentFieldNames")
public class GetBidModifiersCpmDesktopMobileTest {
    private static LogSteps log = LogSteps.getLogger(GetBidModifiersFieldNamesDesktopTest.class);
    private static final String CLIENT = BidModifiersLogins.SINGLE_CLIENT_GET;

    private static Long campaignId;
    private static Long desktopModifierId;
    private static Long mobileWithOsModifierId;
    private static Long mobileWithoutOsModifierId;

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

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

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

    @BeforeClass
    public static void beforeClass() {
        log.info("Подготовим десктопные корректировки ставок");
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(CLIENT);
        campaignId = api.userSteps.campaignSteps().addDefaultCpmBannerCampaign();
        Long adGroupId = api.userSteps.adGroupsSteps().addDefaultCpmBannerKeywordsAdGroup(campaignId);
        Long adGroupId2 = api.userSteps.adGroupsSteps().addDefaultCpmBannerKeywordsAdGroup(campaignId);
        List<Long> ids = api.userSteps.bidModifiersSteps().bidModifiersAdd(
                new BidModifierAddMap()
                        .withAdGroupId(adGroupId)
                        .withDesktopAdjustment(new DesktopAdjustmentMap().defaultDesktopAdjustment()),
                new BidModifierAddMap()
                        .withAdGroupId(adGroupId)
                        .withMobileAdjustment(new MobileAdjustmentMap().defaultMobileAdjustment()
                                .withOperatingSystemType(OperatingSystemTypeEnum.ANDROID)),
                new BidModifierAddMap()
                        .withAdGroupId(adGroupId2)
                        .withMobileAdjustment(new MobileAdjustmentMap().defaultMobileAdjustment()
                                .withOperatingSystemType(null))
        );
        assumeThat("Созданы корректировки", ids, hasSize(3));
        desktopModifierId = ids.get(0);
        mobileWithOsModifierId = ids.get(1);
        mobileWithoutOsModifierId = ids.get(2);
    }

    @Test
    public void getWithoutFilter() {
        List<BidModifierGetItem> bms = api.userSteps.bidModifiersSteps().bidModifiersGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new BidModifiersSelectionCriteriaMap()
                                        .withAllLevels()
                                        .withCampaignIds(campaignId))
                        .withFieldNames(BidModifierFieldEnum.ID)
        );
        assertThat("получены корректировки ставок", bms, hasSize(3));
    }

    @Test
    public void getFilterMobileWithOs() {
        List<BidModifierGetItem> modifiers = api.userSteps.bidModifiersSteps().bidModifiersGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new BidModifiersSelectionCriteriaMap()
                                        .withAllLevels()
                                        .withCampaignIds(campaignId)
                                        .withIds(mobileWithOsModifierId)
                                        .withTypes(BidModifierTypeEnum.MOBILE_ADJUSTMENT))
                        .withFieldNames(BidModifierFieldEnum.ID)
                        .withMobileFieldNames(
                                MobileAdjustmentFieldEnum.OPERATING_SYSTEM_TYPE,
                                MobileAdjustmentFieldEnum.BID_MODIFIER)
        );
        assertThat("получены корректировки ставок", modifiers, hasSize(1));
        assertThat("получена корректировка, соответствующая созданной мобильной",
                modifiers.get(0).getId(), equalTo(mobileWithOsModifierId));
        assertThat("получены корректные поля мобильной корректировки",
                modifiers.get(0).getMobileAdjustment(), beanDifferV5(
                        new MobileAdjustmentGetMap()
                                .withBidModifier(BidModifierAddMap.DEFAULT_BID_MODIFIER)
                                .withOperatingSystemType(OperatingSystemTypeEnum.ANDROID)
                                .getBean()
                ));
    }

    @Test
    public void getFilterMobileWithoutOs() {
        List<BidModifierGetItem> modifiers = api.userSteps.bidModifiersSteps().bidModifiersGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new BidModifiersSelectionCriteriaMap()
                                        .withAllLevels()
                                        .withCampaignIds(campaignId)
                                        .withIds(mobileWithoutOsModifierId)
                                        .withTypes(BidModifierTypeEnum.MOBILE_ADJUSTMENT))
                        .withFieldNames(BidModifierFieldEnum.ID)
                        .withMobileFieldNames(
                                MobileAdjustmentFieldEnum.OPERATING_SYSTEM_TYPE,
                                MobileAdjustmentFieldEnum.BID_MODIFIER)
        );
        assertThat("получены корректировки ставок", modifiers, hasSize(1));
        assertThat("получена корректировка, соответствующая созданной мобильной",
                modifiers.get(0).getId(), equalTo(mobileWithoutOsModifierId));
        assertThat("получены корректные поля мобильной корректировки",
                modifiers.get(0).getMobileAdjustment(), beanDifferV5(
                        new MobileAdjustmentGetMap()
                                .withBidModifier(BidModifierAddMap.DEFAULT_BID_MODIFIER)
                                .withOperatingSystemType(null)
                                .getBean()
                ));
    }

    @Test
    public void getFilterDesktop() {
        List<BidModifierGetItem> modifiers = api.userSteps.bidModifiersSteps().bidModifiersGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new BidModifiersSelectionCriteriaMap()
                                        .withAllLevels()
                                        .withCampaignIds(campaignId)
                                        .withTypes(BidModifierTypeEnum.DESKTOP_ADJUSTMENT))
                        .withFieldNames(BidModifierFieldEnum.ID)
                        .withDesktopFieldNames(DesktopAdjustmentFieldEnum.BID_MODIFIER)
        );
        assertThat("получены корректировки ставок", modifiers, hasSize(1));
        assertThat("получена корректировка, соответствующая созданной десктопной",
                modifiers.get(0).getId(), equalTo(desktopModifierId));
        assertThat("получены корректные поля десктопной корректировки",
                modifiers.get(0).getDesktopAdjustment(), beanDiffer(
                        new DesktopAdjustmentGetMap()
                                .withBidModifier(BidModifierAddMap.DEFAULT_BID_MODIFIER)
                                .getBean()
                ));
    }

}
