package ru.yandex.autotests.direct.api.ads.add.mobileappad;

import java.util.Arrays;
import java.util.Collection;

import com.yandex.direct.api.v5.ads.AdFieldEnum;
import com.yandex.direct.api.v5.ads.AdGetItem;
import com.yandex.direct.api.v5.ads.AddResponse;
import com.yandex.direct.api.v5.ads.GetResponse;
import com.yandex.direct.api.v5.ads.MobileAppAdFieldEnum;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.ads.AdAddItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.AdGetItemMap;
import ru.yandex.autotests.directapi.model.api5.ads.AddRequestMap;
import ru.yandex.autotests.directapi.model.api5.ads.AdsSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.ads.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppAdAddMap;
import ru.yandex.autotests.directapi.model.api5.ads.MobileAppAdGetMap;
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.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.apache.commons.lang3.RandomStringUtils.random;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static ru.yandex.autotests.directapi.steps.banners.AdsSteps.MAX_NUMBER_OF_NARROW_CHARACTERS;
import static ru.yandex.autotests.directapi.steps.banners.AdsSteps.NARROW_CHARACTERS;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.beandiffer.BeanDifferMatcher.beanEquivalent;

/**
 * Created by pavryabov on 16.06.17.
 * https://st.yandex-team.ru/DIRECT-67387
 */
@Aqua.Test
@Features(AdsFeatures.ADD)
@Description("Проверка валидации поля Text. Позитивные сценарии")
@Issue("https://st.yandex-team.ru/DIRECT-65773")
@RunWith(Parameterized.class)
public class AddTextValidationPositiveTest {

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

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

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

    static Long campaignId;
    static Long adGroupId;
    MobileAppAdAddMap mobileAppAdAddMap;

    @Parameterized.Parameter(0)
    public String description;

    @Parameterized.Parameter(1)
    public String text;

    @Parameterized.Parameters(name = "{0}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {"Добавить баннер с русским текстом", "баннер"},
                {"Добавить баннер с текстом из одного символа", "б"},
                {"Добавить баннер с латинским текстом", "English text"},
                {"Добавить баннер c текстом со знаками препинания", "Привет, мир."},
                {"Добавить баннер с текстом, который содержит знак \"!\"", "Привет мир!"},
                {"Добавить баннер с текстом, который содержит знак \"?\"", "Привет мир?"},
                {"Добавить баннер с текстом, содержащим слово максимальной длины",
                        randomAlphabetic(MobileAppAdAddMap.MAX_WORD_IN_TEXT_LENGTH)},
                {"Добавить баннер с текстом, состоящим только из узких символов",
                        random(MAX_NUMBER_OF_NARROW_CHARACTERS + 1, NARROW_CHARACTERS)},
                {"Добавить баннер с текстом, состоящим из максимального числа символов (узкие - только пробелы)",
                        generateValidTextOfLength(MobileAppAdAddMap.MAX_TEXT_LENGTH)},
                {"Добавить баннер с текстом, состоящим из максимального числа символов (много узких)",
                        generateValidTextOfLength(MobileAppAdAddMap.MAX_TEXT_LENGTH - MAX_NUMBER_OF_NARROW_CHARACTERS)
                                + ' ' + random(MAX_NUMBER_OF_NARROW_CHARACTERS - 1, NARROW_CHARACTERS)},
        });
    }

    @BeforeClass
    public static void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(AdsLogins.CLIENT);
        campaignId = api.userSteps.campaignSteps().addDefaultMobileAppCampaign(AdsLogins.CLIENT);
        adGroupId = api.userSteps.adGroupsSteps().addDefaultMobileGroup(campaignId);
    }

    @Before
    public void initMap() {
        mobileAppAdAddMap = new MobileAppAdAddMap()
                .withText(text)
                .withTitle(MobileAppAdAddMap.DEFAULT_TITLE)
                .withAction(MobileAppAdAddMap.DEFAULT_ACTION);
    }

    @Test
    public void addWithTextAndCheckSave() {
        //DIRECT-41067
        AddResponse response = api.userSteps.adsSteps().shouldGetResultOnAdd(new AddRequestMap()
                .withAds(new AdAddItemMap()
                        .withMobileAppAd(mobileAppAdAddMap)
                        .withAdGroupId(adGroupId)), ExpectedResult.success());
        Long id = response.getAddResults().get(0).getId();
        GetResponse getResponse = api.userSteps.adsSteps().adsGet(new GetRequestMap()
                .withSelectionCriteria(new AdsSelectionCriteriaMap().withIds(id))
                .withFieldNames(AdFieldEnum.ID)
                .withMobileAppAdFieldNames(MobileAppAdFieldEnum.TEXT));
        assertThat("текст баннера сохранился верно", getResponse.getAds(), beanEquivalent(
                Arrays.asList((AdGetItem) new AdGetItemMap().withId(id).withMobileAppAd(
                        new MobileAppAdGetMap().withText(text)).getBean())));
    }

    private static String generateValidTextOfLength(int length) {
        StringBuilder stringBuilder = new StringBuilder(randomAlphabetic(length));
        int wordLength = MobileAppAdAddMap.MAX_WORD_IN_TEXT_LENGTH;
        for (int i = wordLength; i < length; i += wordLength) {
            stringBuilder.setCharAt(i, ' ');
        }
        return stringBuilder.toString();
    }
}
