package ru.yandex.autotests.direct.api.campaigns.update.mobilecampaign;

import java.util.List;
import java.util.stream.Collectors;

import com.yandex.direct.api.v5.general.ActionResult;
import org.hamcrest.Matchers;
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.campaigns.CampaignsFeatures;
import ru.yandex.autotests.direct.api.campaigns.CampaignsLogins;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BsResyncQueueRecord;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.enums.StatusBsSynced;
import ru.yandex.autotests.directapi.model.api5.ads.AdAddItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.AddRequestMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppAdAddMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.CampaignUpdateItemMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.UpdateRequestMap;
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.qatools.Tag;
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.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;

/**
 * Created by hmepas on 06.09.2018.
 * https://st.yandex-team.ru/DIRECT-78409
 */
@Aqua.Test
@Issue("https://st.yandex-team.ru/DIRECT-78409")
@Features(CampaignsFeatures.UPDATE)
@Description("Проверка отправки объявлений на модерацию после обновления названия РМП кампании")
@Tag(TagDictionary.TRUNK)
public class SendAdsToBsOnUpdateMobileAppCampaignNameTest {
    private static int bsResendPriority = 107;
    private static String client = CampaignsLogins.UPDATE_CLIENT;
    private static int shard;
    private static Long cid;
    private static Long pid;
    private static List<Long> sendToBsBids;

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

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

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

    @BeforeClass
    public static void prepare() {
        shard = api.userSteps.getDarkSideSteps().getClientFakeSteps().getUserShard(client);
        cid = api.userSteps.campaignSteps().addDefaultMobileAppCampaign();
        pid = api.userSteps.adGroupsSteps().addDefaultMobileGroup(cid);

        String trackingUrlPrefix = "https://appmetrica.yandex.com/serve/7438548069196542965/?click_id={LOGID}";
        // создаем 5 объявлений, 4 с макросом и одно без, переотправится в БК
        // должно только то, что без макроса
        final List<ActionResult> addResults = api.userSteps.adsSteps().shouldGetResultOnAdd(
                new AddRequestMap().withAds(
                        new AdAddItemMap()
                                .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd().withTrackingUrl(trackingUrlPrefix))
                                .withAdGroupId(pid),
                        new AdAddItemMap()
                                .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd().withTrackingUrl(trackingUrlPrefix+"&cname={campaign_name}"))
                                .withAdGroupId(pid),
                        new AdAddItemMap()
                                .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd().withTrackingUrl(trackingUrlPrefix+"&cname={campaignname}"))
                                .withAdGroupId(pid),
                        new AdAddItemMap()
                                .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd().withTrackingUrl(trackingUrlPrefix+"&cname={campaign_name_lat}"))
                                .withAdGroupId(pid),
                        new AdAddItemMap()
                                .withMobileAppAd(new MobileAppAdAddMap().defaultMobileAppAd().withTrackingUrl(trackingUrlPrefix+"&cname={campaignnamelat}"))
                                .withAdGroupId(pid)
                ),
                ExpectedResult.success(),
                ExpectedResult.success(),
                ExpectedResult.success(),
                ExpectedResult.success(),
                ExpectedResult.success()
        ).getAddResults();

        final List<Long> addedBids = addResults.stream().map(ar -> ar.getId()).collect(Collectors.toList());
        sendToBsBids = addedBids.subList(1,5);

        Long keywordId = api.userSteps.keywordsSteps().addDefaultKeyword(pid);
        api.userSteps.campaignFakeSteps().makeNewCampaignReadyForSendingToBS(cid);
        api.userSteps.groupFakeSteps().makeGroupFullyModerated(pid);
        api.userSteps.groupFakeSteps().setGroupFakeStatusBsSynced(pid, StatusBsSynced.YES.toString());
        api.userSteps.phrasesFakeSteps().makePhraseActive(keywordId);

        api.userSteps.bannersFakeSteps().makeBannersActiveAndFullyModerated(addedBids.toArray(new Long[5]));
    }

    @Test
    public void updateCampaignAndCheckStatus() {
        api.userSteps.campaignSteps().shouldGetResultOnUpdate(new UpdateRequestMap().withCampaigns(
                new CampaignUpdateItemMap().withId(cid).withName("New Campaign name updated")
        ), ExpectedResult.success());

        final List<BsResyncQueueRecord> bsResyncQueueRecords =
                api.userSteps.getDirectJooqDbSteps().useShard(shard).bsResyncQueueSteps()
                        .getBsResyncQueueRecordsByCid(cid);

        List<Long> bidsInBsResyncQueue = bsResyncQueueRecords.stream().filter(r -> r.getPriority() == bsResendPriority)
                .map(r -> r.getBid()).collect(Collectors.toList());

        assumeThat("4 из 5ти объявлений отправлены в БК, через очередь", bsResyncQueueRecords, hasSize(4));
        assertThat("В БК через очередь отправлены объявления с макросом", bidsInBsResyncQueue,
                Matchers.containsInAnyOrder(sendToBsBids.toArray()));
    }
}
