package ru.yandex.autotests.direct.api.ads.delete;

import com.yandex.direct.api.v5.campaigns.CampaignFieldEnum;
import com.yandex.direct.api.v5.campaigns.CampaignStateGetEnum;
import com.yandex.direct.api.v5.campaigns.GetResponse;
import org.junit.Before;
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.ads.AdsFeatures;
import ru.yandex.autotests.direct.api.ads.AdsLogins;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetails;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.fake.BannerFakeInfo;
import ru.yandex.autotests.directapi.model.api5.campaigns.CampaignsSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.general.ExpectedResult;
import ru.yandex.autotests.directapi.model.api5.general.IdsCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.general.Notification;
import ru.yandex.autotests.directapi.model.campaigns.Status;
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.allure.annotations.Step;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by semkagtn on 14.05.15.
 * https://st.yandex-team.ru/TESTIRT-5497
 */
@Aqua.Test
@Features(AdsFeatures.DELETE)
@Description("Id, которые должны вызывать ошибку в запросе на удаление объявления")
@Issue("https://st.yandex-team.ru/DIRECT-39274")
@Tag(TagDictionary.TRUNK)
public class IdsNegativeTest {

    private static final String LOGIN = AdsLogins.CLIENT;
    private static final String ANOTHER_LOGIN = AdsLogins.CLIENT_ELSE;

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

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

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

    private Long campaignId;
    private Long adGroupId;
    private Long id;

    @BeforeClass
    public static void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(LOGIN);
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(ANOTHER_LOGIN);
    }

    @Before
    @Step("Подготовка данных для теста")
    public void createAd() {
        api.as(LOGIN);
        campaignId = api.userSteps.campaignSteps().addDefaultTextCampaign(LOGIN);
        adGroupId = api.userSteps.adGroupsSteps().addDefaultGroup(campaignId);
        id = api.userSteps.adsSteps().addDefaultTextAd(adGroupId);
    }

    @Test
    @Description("Нулевой идентификатор объявления в запросе")
    public void deleteZeroId() {
        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(0L),
                        ExpectedResult.errors(new Notification(8800, Api5ErrorDetails.AD_NOT_FOUND)));
    }

    @Test
    @Description("Чужой идентификатор объявления в запросе")
    public void deleteNotMyId() {
        api.as(ANOTHER_LOGIN);
        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id),
                        ExpectedResult.errors(new Notification(8800, Api5ErrorDetails.AD_NOT_FOUND)));
    }

    @Test
    @Description("Удалённый идентификатор объявления в запросе")
    public void deleteDeletedId() {
        api.userSteps.adsSteps().adsDelete(id);
        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id),
                        ExpectedResult.errors(new Notification(8800, Api5ErrorDetails.AD_NOT_FOUND)));
    }

    @Test
    @Description("Идентификатор объявления из удалённой кампании в запросе")
    public void deleteIdFromDeletedCampaign() {
        api.userSteps.campaignSteps().campaignsDelete(campaignId);
        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id),
                        ExpectedResult.errors(new Notification(8800, Api5ErrorDetails.AD_NOT_FOUND)));
    }

    @Test
    @Issue("https://st.yandex-team.ru/DIRECT-41952")
    @Description("Идентификатор объявления из заархивированной кампании в запросе")
    public void deleteIdFromArchivedCampaign() {
        api.userSteps.archiveCampaign(campaignId);
        GetResponse response = api.userSteps.campaignSteps().campaignsGet(new GetRequestMap()
                .withSelectionCriteria(new CampaignsSelectionCriteriaMap().withIds(campaignId))
                .withFieldNames(CampaignFieldEnum.ID, CampaignFieldEnum.STATE));
        CampaignStateGetEnum state = response.getCampaigns().get(0).getState();
        assumeThat("кампания заархивировалась", state, equalTo(CampaignStateGetEnum.ARCHIVED));

        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id),
                        ExpectedResult.errors(new Notification(8300,
                                Api5ErrorDetails.UNABLE_UPDATE_ARCHIVED_CAMPAGN)));
    }

    @Test
    @Description("Несуществующий идентификатор объявления в запросе")
    public void deleteNonExistentId() {
        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id + 500_000),
                        ExpectedResult.errors(new Notification(8800, Api5ErrorDetails.AD_NOT_FOUND)));
    }

    @Test
    @Description("Отрицательный идентификатор объявления в запросе")
    public void deleteNegativeId() {
        api.userSteps.adsSteps()
                .shouldGetResultOnDelete(new IdsCriteriaMap().withIds(-id),
                        ExpectedResult.errors(new Notification(8800, Api5ErrorDetails.AD_NOT_FOUND)));
    }

    @Test
    @Description("Удалить активное объявление")
    public void deleteActiveAd() {
        api.userSteps.bannersFakeSteps().makeBannerActive(id);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(id);
        assumeThat("объявление является активным", bannerFakeInfo.getStatusActive(), equalTo(Status.YES));
        api.userSteps.adsSteps().shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id),
                ExpectedResult.errors(new Notification(8300, Api5ErrorDetails.AD_CANT_BE_DELETED)));
    }

    @Test
    @Description("Удалить объявление, отправленное в БК")
    public void deleteAdSentInBS() {
        api.userSteps.bannersFakeSteps().setBannerRandomFakeBannerID(id);
        BannerFakeInfo bannerFakeInfo = api.userSteps.bannersFakeSteps().getBannerParams(id);
        assumeThat("объявление считается отправленным в БК", bannerFakeInfo.getBannerID(), notNullValue());
        api.userSteps.adsSteps().shouldGetResultOnDelete(new IdsCriteriaMap().withIds(id),
                ExpectedResult.errors(new Notification(8300, Api5ErrorDetails.AD_CANT_BE_DELETED)));
    }
}
