package ru.yandex.autotests.directapi.campaigns.geteventslog.banner;

import java.util.Arrays;

import com.yandex.direct.api.v5.ads.AdFieldEnum;
import com.yandex.direct.api.v5.ads.TextAdFieldEnum;
import org.junit.Before;
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.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.direct.utils.textresource.TextResourceFormatter;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.campaigns.CampaignFeatures;
import ru.yandex.autotests.directapi.campaigns.CampaignLogins;
import ru.yandex.autotests.directapi.common.api45.EventsLogItem;
import ru.yandex.autotests.directapi.model.api5.ads.AdsSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.ads.GetRequestMap;
import ru.yandex.autotests.directapi.model.banners.BannerModerationResult;
import ru.yandex.autotests.directapi.model.common.Value;
import ru.yandex.autotests.directapi.model.geteventslog.EventName;
import ru.yandex.autotests.directapi.model.geteventslog.EventType;
import ru.yandex.autotests.directapi.model.geteventslog.EventsLogItemMap;
import ru.yandex.autotests.directapi.model.geteventslog.GetEventsLogFilterMap;
import ru.yandex.autotests.directapi.model.geteventslog.GetEventsLogRequestMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.steps.UserSteps;
import ru.yandex.autotests.irt.testutils.allure.LogSteps;
import ru.yandex.qatools.Tag;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static ru.yandex.autotests.direct.utils.matchers.BeanEquals.beanEquals;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;


/**
 * Migrated from old school project (api4l)
 * <br/>
 * Created by chicos on 04.02.14.<br/>
 * https://jira.yandex-team.ru/browse/TESTIRT-1400
 */
@Aqua.Test
@Features(CampaignFeatures.GET_EVENTS_LOG)
@Tag(TagDictionary.TRUNK)
public class GetBannerModeratedEventsTest {

    protected LogSteps log = LogSteps.getLogger(this.getClass());

    private static final String CLIENT_LOGIN = CampaignLogins.SELF_CLIENT;
    private static final Currency CLIENT_CURRENCY = Currency.RUB;

    private static EventsLogItemMap bannerEvent;

    private static String timestampBefore;
    private static String timestampAfter;

    private static Long campaignId;
    private static Long adId;
    private static String adTitle;

    @ClassRule
    public static ApiSteps api = new ApiSteps().version(104).as(CLIENT_LOGIN);

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

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


    @Before
    public void prepareEvents()  {
        api.userSteps.clientFakeSteps().setAPIUnits(CLIENT_LOGIN,100000);

        campaignId = api.userSteps.campaignSteps().addDefaultTextCampaign();

        final UserSteps.AdGroupCreationResult adGroupCreationResult =
                api.userSteps.addCompletedAdGroupAndReturnCreationResult(campaignId);

        adId = adGroupCreationResult.getAdIds()[0];
        adTitle = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(new AdsSelectionCriteriaMap().withIds(adId))
                .withFieldNames(AdFieldEnum.ID)
                .withTextAdFieldNames(TextAdFieldEnum.TITLE)
        ).getAds().get(0).getTextAd().getTitle();
        api.userSteps.bannersFakeSteps().makeBannersModerated(adId);

        timestampBefore = api.userSteps.changesSteps().getTimestamp();
        bannerEvent = new EventsLogItemMap(api.type())
            .bannerModeratedEvent(
                    campaignId.intValue(), adId, BannerModerationResult.ACCEPTED, Value.YES);
        api.userSteps.eventLogFakeSteps().addEvents(bannerEvent);
        TextResourceFormatter stringResource = TextResourceFormatter.resource(EventName.BANNER_MODERATED);
        bannerEvent.withEventName(stringResource.toString()).withTimestamp(null);

        timestampAfter = api.userSteps.changesSteps().getTimestamp();
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5535")
    public void getEventByEmptyFilter()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
        );
        bannerEvent.withTextDescription(null);
        assertThat("присутствует событие", Arrays.asList(events),
                hasItem(beanEquals((EventsLogItem) bannerEvent.getBean())));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5536")
    public void getEventByPausedByDayBudgetType()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.PAUSEDBYDAYBUDGET))
        );

        assertThat("присутствует событие", Arrays.asList(events),
                not(hasItem(beanEquals((EventsLogItem) bannerEvent.getBean()))));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5537")
    public void getEventByBannerModeratedType()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.BANNERMODERATED))
        );

        bannerEvent.withTextDescription(null);
        assertThat("присутствует событие", Arrays.asList(events),
                (hasItem(beanEquals((EventsLogItem) bannerEvent.getBean()))));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5538")
    public void getEventByCampaignId()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.BANNERMODERATED)
                                .withCampaignIDS(campaignId.intValue()))
        );
        bannerEvent.withTextDescription(null);

        assertThat("присутствует событие", Arrays.asList(events),
                hasItem(beanEquals((EventsLogItem) bannerEvent.getBean())));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5539")
    public void getEventByBannerId()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withBannerIDS(adId))
        );
        bannerEvent.withTextDescription(null);

        assertThat("присутствует событие", Arrays.asList(events),
                hasItem(beanEquals((EventsLogItem) bannerEvent.getBean())));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5540")
    public void getEventWithTextDescription()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.BANNERMODERATED)
                                .withBannerIDS(adId))
                        .withWithTextDescription(Value.YES)
        );

        bannerEvent.withTextDescription(adTitle);
        assertThat("присутствует событие", Arrays.asList(events),
                hasItem(beanEquals((EventsLogItem) bannerEvent.getBean())));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5541")
    public void getEventWithLastEventOnly()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.BANNERMODERATED))
                        .withWithTextDescription(Value.YES)
                        .withLastEventOnly(Value.YES)
        );

        bannerEvent.withTextDescription(adTitle);
        assertThat("присутствует событие", Arrays.asList(events),
                hasItem(beanEquals((EventsLogItem) bannerEvent.getBean())));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5542")
    public void getEventWithTimestampAfterEvent()  {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withCurrency(CLIENT_CURRENCY)
                        .withTimestampFrom(timestampAfter)
        );

        bannerEvent.withTextDescription(null);
        assertThat("присутствует событие", Arrays.asList(events),
                not(hasItem(beanEquals((EventsLogItem) bannerEvent.getBean()))));
    }

    @Test
    public void eventFilteredForDeletedBanner() {
        api.userSteps.adsSteps().adsDelete(adId);
        api.userSteps.getDirectJooqDbSteps().shardingSteps().deleteBid(adId);
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestampBefore)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withBannerIDS(adId))
        );
        bannerEvent.withTextDescription(null);

        assertThat("событий нет", events, emptyArray());
    }
}
