package ru.yandex.autotests.direct.api.adimages.get;

import com.yandex.direct.api.v5.general.YesNoEnum;
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.api.adimages.AdImagesFeatures;
import ru.yandex.autotests.direct.api.adimages.AdImagesLogins;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.apiclient.errors.Api5Error;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetails;
import ru.yandex.autotests.directapi.enums.ImageType;
import ru.yandex.autotests.directapi.model.api5.adimages.AdImageSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.adimages.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.ads.AdAddItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.TextAdAddMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
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.apache.commons.lang3.StringUtils.capitalize;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by ginger on 09.02.16.
 * https://st.yandex-team.ru/TESTIRT-8445
 */
@Aqua.Test
@Features(AdImagesFeatures.GET)
@Description("Проверка списания баллов API за вызов метода Get")
@Issue("https://st.yandex-team.ru/DIRECT-50157")
public class AdImagesUnitTest {
    private static String client = AdImagesLogins.CLIENT_GET_8;
    private String associatedHash;
    int GET_COST = 15;
    int GET_COST_IMAGE = 1;
    public int DEFAULT_FAULT_COST = 50;
    public static String PARAMS =  "params";

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

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

    @Rule
    public Trashman trasher = new Trashman(api);
    private String[] hashes;

    @Before
    @Step("Подготовка данных для теста")
    public void addImage() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        hashes = api.userSteps.imagesSteps().configLoginImages(client, ImageType.REGULAR, 1, 2);
        associatedHash = hashes[0];
        Long campaignId = api.userSteps.campaignSteps().addDefaultTextCampaign();
        Long adGroupId = api.userSteps.adGroupsSteps().addDefaultGroup(campaignId);
        api.userSteps.adsSteps().addAd(
                new AdAddItemMap()
                        .withTextAd(
                                new TextAdAddMap()
                                        .defaultTextAd()
                                        .withAdImageHash(associatedHash))
                        .withAdGroupId(adGroupId));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("2435")
    public void successGetWithNoImageTest() {
        int unitsBefore = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        api.userSteps.imagesStepsV5().adImagesGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new AdImageSelectionCriteriaMap()
                                        .withAdImageHashes(hashes[0])
                                        .withAssociated(YesNoEnum.NO)
                        )
                        .withAllFieldNames()
        );
        int unitsAfter = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        assertThat("списалось правильное количество баллов",
                unitsBefore - unitsAfter, equalTo(GET_COST));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("2436")
    public void successGetWithOneImageTest() {
        int unitsBefore = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        api.userSteps.imagesStepsV5().adImagesGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new AdImageSelectionCriteriaMap()
                                        .withAdImageHashes(hashes[0],hashes[1])
                                        .withAssociated(YesNoEnum.YES)
                        )
                        .withAllFieldNames()
        );
        int unitsAfter = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        assertThat("списалось правильное количество баллов",
                unitsBefore - unitsAfter, equalTo(GET_COST + GET_COST_IMAGE));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("2437")
    public void successGetWithTwoImagesTest(){
        int unitsBefore = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        api.userSteps.imagesStepsV5().adImagesGet(
                new GetRequestMap()
                        .withSelectionCriteria(
                                new AdImageSelectionCriteriaMap()
                                        .withAdImageHashes(hashes[0],hashes[1])
                        )
                        .withAllFieldNames()
        );
        int unitsAfter = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        assertThat("списалось правильное количество баллов",
                unitsBefore - unitsAfter, equalTo(GET_COST + 2 * GET_COST_IMAGE));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("2433")
    public void getImageWithNoUnits(){
        int units = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        api.userSteps.clientFakeSteps().fakeWithdrawClientUnits(client, units);
        units = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        assumeThat("у клиента не осталось баллов", units, equalTo(0));
        api.userSteps.imagesStepsV5().expectErrorOnAdImagesGet(
                new GetRequestMap()
                .withSelectionCriteria(
                        new AdImageSelectionCriteriaMap()
                                .withAdImageHashes(hashes[0],hashes[1])
                )
                .withAllFieldNames(),
                client,
                new Api5Error(152, Api5ErrorDetails.NOT_ENOUGH_UNITS_FOR_OPERATION)
        );
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("2434")
    public void getImagesWithFaultError(){
        int unitsBefore = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        api.userSteps.imagesStepsV5().expectErrorOnAdImagesGet(
                new GetRequestMap().withSelectionCriteria(null),
                new Api5Error(8000, Api5ErrorDetails.MISSING_REQUIRED_FIELD, PARAMS,
                        capitalize(GetRequestMap.FIELD_NAMES))
        );
        int unitsAfter = api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client);
        assertThat("списалось правильное количество баллов",
                unitsBefore - unitsAfter, equalTo(DEFAULT_FAULT_COST));
    }
}
