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

import java.util.Arrays;

import com.yandex.direct.api.v5.keywords.KeywordFieldEnum;
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.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.keywords.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.keywords.KeywordsSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.banners.phrases.BannerPhraseInfoMap;
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.autotests.irt.testutils.beandiffer.beanconstraint.BeanConstraints;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
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)
public class GetWarnPlaceEventsTest {

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

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

    private static EventsLogItemMap warnEvent;
    private static EventsLogItemMap moneyOutEvent;

    private static String timestamp1;
    private static String timestamp2;
    private static String timestampAfter;

    private static Long campaignId;
    private static Long bannerId;
    public static String keywordText;

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

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

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

    @BeforeClass
    public static void prepareEvents() {
        api.userSteps.clientFakeSteps().setAPIUnits(clientLogin,100000);

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

        final UserSteps.AdGroupCreationResult adGroupCreationResult =
                api.userSteps.addCompletedAdGroupAndReturnCreationResult(campaignId);
        bannerId = adGroupCreationResult.getAdIds()[0];
        BannerPhraseInfoMap phraseInfo = api.userSteps.creationResultToBannerPhraseInfo(campaignId, adGroupCreationResult);
        api.userSteps.bannersFakeSteps().makeBannersModerated(bannerId);

        Long keywordId = adGroupCreationResult.getKeywordIds()[0];
        keywordText = api.userSteps.keywordsSteps().keywordsGet(
                new GetRequestMap().withSelectionCriteria(
                        new KeywordsSelectionCriteriaMap().withIds(keywordId)
                ).withFieldNames(KeywordFieldEnum.KEYWORD)).get(0).getKeyword();

        timestamp1 = api.userSteps.changesSteps().getTimestamp();
        warnEvent = new EventsLogItemMap(api.type()).warnPlaceEvent(phraseInfo, "3");
        api.userSteps.eventLogFakeSteps().addEvents(warnEvent);
        warnEvent.withEventName(TextResourceFormatter.resource(EventName.WARN_PLACE).toString()).withTimestamp(null);

        timestamp2 = api.userSteps.changesSteps().getTimestamp();
        moneyOutEvent = new EventsLogItemMap(api.type()).moneyOutEvent(campaignId.intValue());
        api.userSteps.eventLogFakeSteps().addEvents(moneyOutEvent);
        moneyOutEvent.withEventName(TextResourceFormatter.resource(EventName.MONEY_OUT).toString()).withTimestamp(null);
        timestampAfter = api.userSteps.changesSteps().getTimestamp();
    }

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

        warnEvent.withTextDescription(null);
        moneyOutEvent.withTextDescription(null);
        assertThat("присутствуют события", Arrays.asList(events),
                hasItems(
                        beanEquals((EventsLogItem) warnEvent.getBean()),
                        beanEquals((EventsLogItem) moneyOutEvent.getBean())));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5549")
    public void getEventByMoneyWarningType() {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestamp1)
                        .withTimestampTo(timestampAfter)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.MONEYWARNING))
        );

        warnEvent.withTextDescription(null);
        moneyOutEvent.withTextDescription(null);
        assertThat("отсутствуют некоторые события", Arrays.asList(events),
                not(hasItems(
                        beanEquals((EventsLogItem) warnEvent.getBean()),
                        beanEquals((EventsLogItem) moneyOutEvent.getBean()))));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5550")
    public void getEventByWarnPlaceType() {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestamp1)
                        .withTimestampTo(timestampAfter)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.WARNPLACE))
        );

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

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5544")
    public void getEventByCampaignId() {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestamp1)
                        .withTimestampTo(timestamp2)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withCampaignIDS(campaignId.intValue()))
        );

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

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5545")
    public void getEventByBannerId() {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestamp1)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withBannerIDS(bannerId))
        );

        warnEvent.withTextDescription(null);
        assertThat("присутствуют события", Arrays.asList(events),
                hasItems(
                        beanEquals((EventsLogItem) warnEvent.getBean())));
    }

    @Test
    //https://jira.yandex-team.ru/browse/DIRECT-28423
    @ru.yandex.qatools.allure.annotations.TestCaseId("5546")
    public void getEventWithTextDescription() {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestamp1)
                        .withCurrency(CLIENT_CURRENCY)
                        .withFilter(new GetEventsLogFilterMap(api.type())
                                .withEventType(EventType.WARNPLACE))
                        .withWithTextDescription(Value.YES)
        );

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

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("5547")
    public void getEventWithLastEventOnly() {
        EventsLogItem[] events = api.userSteps.getEventsLogSteps().getEventsLog(
                new GetEventsLogRequestMap(api.type())
                        .withTimestampFrom(timestamp1)
                        .withTimestampTo(timestampAfter)
                        .withLastEventOnly(Value.YES)
                        .withCurrency(CLIENT_CURRENCY)
        );
        warnEvent.withTextDescription(null);
        moneyOutEvent.withTextDescription(null);

        assertThat("присутствуют события", Arrays.asList(events),
                hasItems(
                        beanEquals((EventsLogItem) warnEvent.getBean()),
                        beanEquals((EventsLogItem) moneyOutEvent.getBean())));
    }

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

        warnEvent.withTextDescription(null);
        moneyOutEvent.withTextDescription(null);
        assertThat("отсутствуют некоторые события", Arrays.asList(events),
                not(hasItems(
                        beanEquals((EventsLogItem) warnEvent.getBean()),
                        beanEquals((EventsLogItem) moneyOutEvent.getBean()))));
    }
}
