package ru.yandex.autotests.directapi.images.association.set;

import org.junit.*;
import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.fake.BannerFakeInfo;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.fake.GroupFakeInfo;
import ru.yandex.autotests.directapi.darkside.model.Status;
import ru.yandex.autotests.directapi.enums.ImageType;
import ru.yandex.autotests.directapi.images.ImagesFeatures;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.images.ImageLogins;
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.allure.annotations.Issue;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.core.IsEqual.equalTo;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by pavryabov on 21.04.15.
 * https://st.yandex-team.ru/TESTIRT-5245
 */
@Aqua.Test
@Features(ImagesFeatures.AD_IMAGE_ASSOCIATION_SET)
@Description("Удаление картинки должно приводить к сбросу StatusBsSynced. Неудачная попытка - нет")
@Issue("https://st.yandex-team.ru/DIRECT-41165")
public class StatusBsSyncedTest {

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

    static String login = ImageLogins.LOGIN_WITH_ASSIGNED_IMAGES_12;

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

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

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

    private Long campaignID;
    private Long adGroupID;
    private Long adID;
    private String hash1;
    private String hash2;

    @Step("Подготовка данных для теста")
    @Before
    public void assignImage() {
        campaignID = api.userSteps.campaignStepsV5().addDefaultTextCampaign(login);
        adGroupID = api.userSteps.adGroupsSteps().addDefaultGroup(campaignID, login);
        api.userSteps.keywordsSteps().addDefaultKeyword(login, adGroupID);
        adID = api.userSteps.adsSteps().addDefaultTextAd(adGroupID, login);
        //api.userSteps.adsSteps().adsModerate(adID);

        String[] hashes = api.userSteps.imagesSteps().configLoginImages(login, ImageType.REGULAR, 1, 2);
        hash1 = hashes[0];
        hash2 = hashes[1];
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("7618")
    public void deleteImageFromBanner() {
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash1);
        api.userSteps.bannersFakeSteps().setStatusBsSynced(adID, Status.YES);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assumeThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.imagesSteps().setAdImageAssociation(adID, null);
        bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assertThat("StatusBsSynced = No", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.NO));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("7619")
    public void deleteImageFromBannerWithoutImage() {
        api.userSteps.bannersFakeSteps().setStatusBsSynced(adID, Status.YES);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assumeThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.imagesSteps().setAdImageAssociation(adID, null);
        bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assertThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("7620")
    public void deleteDeletedImageFromBanner() {
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash1);
        api.userSteps.imagesSteps().setAdImageAssociation(adID, null);
        api.userSteps.bannersFakeSteps().setStatusBsSynced(adID, Status.YES);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assumeThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.imagesSteps().setAdImageAssociation(adID, null);
        bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assertThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
    }

    @Test
    public void assignImageToBanner() {
        api.userSteps.bannersFakeSteps().setStatusBsSynced(adID, Status.YES);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assumeThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash1);
        bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assertThat("StatusBsSynced = No", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.NO));
    }

    @Test
    public void reassignImageToBanner() {
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash1);
        api.userSteps.bannersFakeSteps().setStatusBsSynced(adID, Status.YES);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assumeThat("StatusBsSynced = Yes", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash2);
        bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(adID);
        assertThat("StatusBsSynced = No", bannerFakeInfo.getStatusBsSynced(), equalTo(Status.NO));
    }

    @Test
    public void assignImageToBannerAndCheckGroupStatus() {
        api.userSteps.groupFakeSteps().setGroupFakeStatusBsSynced(adGroupID, Status.YES);
        GroupFakeInfo groupFakeInfo = api.userSteps.groupFakeSteps().getGroupParams(adGroupID);
        assumeThat("StatusBsSynced = Yes", groupFakeInfo.getStatusBsSynced(), equalTo(Status.YES));

        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash1);

        groupFakeInfo = api.userSteps.groupFakeSteps().getGroupParams(adGroupID);
        // Этот тест проверяет корректное поведение, что StatusBsSynced на группе обновляется. Тест фейлится тоже
        // корректно из-за баги, AdImageAssociation обновляет группу по полю bid, которое в api4 заполняется
        // (вполне возможно не всегда корректно), а в api5 не заполняется вообще
        // Еще один тест-кейс - группа с двумя-тремя баннерами, проверить, проставляется ли статус для каждого
        // из них, поле bid в группе одно
        assertThat("StatusBsSynced = No", groupFakeInfo.getStatusBsSynced(), equalTo(Status.NO));
    }

    @Test
    public void reassignImageToBannerAndCheckGroupStatus() {
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash1);
        api.userSteps.groupFakeSteps().setGroupFakeStatusBsSynced(adGroupID, Status.YES);
        GroupFakeInfo groupFakeInfo = api.userSteps.groupFakeSteps().getGroupParams(adGroupID);
        assumeThat("StatusBsSynced = Yes", groupFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.imagesSteps().setAdImageAssociation(adID, hash2);
        groupFakeInfo = api.userSteps.groupFakeSteps().getGroupParams(adGroupID);
        // Этот тест проверяет корректное поведение, что StatusBsSynced на группе обновляется. Тест фейлится тоже
        // корректно из-за баги, AdImageAssociation обновляет группу по полю bid, которое в api4 заполняется
        // (вполне возможно не всегда корректно), а в api5 не заполняется вообще
        // Еще один тест-кейс - группа с двумя-тремя баннерами, проверить, проставляется ли статус для каждого
        // из них, поле bid в группе одно
        assertThat("StatusBsSynced = No", groupFakeInfo.getStatusBsSynced(), equalTo(Status.NO));
    }
}
