package ru.yandex.autotests.direct.api.campaigns.add.negativekeywords;

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

import org.apache.commons.lang3.RandomStringUtils;
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.campaigns.CampaignsFeatures;
import ru.yandex.autotests.direct.api.campaigns.CampaignsLogins;
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.model.api5.campaigns.AddRequestMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.CampaignAddItemMap;
import ru.yandex.autotests.directapi.model.api5.general.ExpectedResult;
import ru.yandex.autotests.directapi.model.api5.general.JavaOrPerlExpectedResult;
import ru.yandex.autotests.directapi.model.api5.general.Notification;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.steps.banners.KeywordsSteps;
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.apache.commons.lang.WordUtils.capitalize;

@Aqua.Test
@Features(CampaignsFeatures.ADD)
@Description("Проверка валидации поля NegativeKeywords для минус фраз. Негативные сценарии")
@Issue("https://st.yandex-team.ru/TESTIRT-10419")
@Tag(TagDictionary.TRUNK)
@RunWith(Parameterized.class)
public class NegativeKeyPhrasesValidationNegativeTest {
    private static final String CLIENT = CampaignsLogins.CLIENT;

    @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);

    @Parameterized.Parameter(0)
    public String description;

    @Parameterized.Parameter(1)
    public String[] negativeKeyPhrases;

    @Parameterized.Parameter(2)
    public JavaOrPerlExpectedResult expectedResult;

    @Parameterized.Parameters(name = "{0}")
    public static Collection testData() {
        String phraseWithSixWords = "медведь перешьет себе теплую шубу на зиму";
        String moreThanMaxLengthNegativeWord =
                RandomStringUtils.randomAlphabetic(KeywordsSteps.MINUS_WORD_MAX_LENGTH + 1);
        String moreThanMaxWordInNegativePhrase = "белый " + phraseWithSixWords;
        ArrayList<String> moreThanMaxLengthNegativePhrasesList = new ArrayList<>();
        int allPhrasesLength = 0;
        while (allPhrasesLength <= (CampaignAddItemMap.MAX_NEGATIVE_KEYWORDS_LENGTH)) {
            allPhrasesLength = allPhrasesLength + KeywordsSteps.MINUS_WORD_MAX_LENGTH;
            moreThanMaxLengthNegativePhrasesList
                    .add(RandomStringUtils.randomAlphabetic(KeywordsSteps.MINUS_WORD_MAX_LENGTH));
        }
        moreThanMaxLengthNegativePhrasesList.add(phraseWithSixWords);
        if (CampaignAddItemMap.MAX_NEGATIVE_KEYWORDS_LENGTH - allPhrasesLength > 0) {
            moreThanMaxLengthNegativePhrasesList.add(
                    RandomStringUtils.randomAlphabetic(KeywordsSteps.MINUS_WORD_MAX_LENGTH)
                            .substring(0, CampaignAddItemMap.MAX_NEGATIVE_KEYWORDS_LENGTH - allPhrasesLength + 1));
        }
        Object[][] data = new Object[][]{
                {"More than 7 words in negative key phrase ", new String[]{moreThanMaxWordInNegativePhrase},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(
                                new Notification(5002,
                                        Api5ErrorDetails.NUMBER_OF_WORDS_IN_NEGATIVE_KEYPHRASE_GREATER_THAN,
                                        CampaignAddItemMap.MAX_WORDS_IN_NEGATIVE_KEYPHRASE,
                                        moreThanMaxWordInNegativePhrase)))},
                {"More than 35 symbol for word in negative key phrase",
                        new String[]{"белый медведь шьет " + moreThanMaxLengthNegativeWord},
                        JavaOrPerlExpectedResult
                                .java(ExpectedResult.errorsIgnoringDetails(new Notification(5162,
                                        Api5ErrorDetails.LENGTH_OF_NEGATIVE_KEYWORDS_LONGER_THAN,
                                        KeywordsSteps.MINUS_WORD_MAX_LENGTH,
                                        "белый медведь шьет " + moreThanMaxLengthNegativeWord)))
                                .perl(ExpectedResult.errors(new Notification(5162,
                                        Api5ErrorDetails.LENGTH_OF_NEGATIVE_KEYWORDS_LONGER_THAN,
                                        KeywordsSteps.MINUS_WORD_MAX_LENGTH,
                                        "белый медведь шьет " + moreThanMaxLengthNegativeWord)))},
                {"More than 20000 symbol for negative key phrase", moreThanMaxLengthNegativePhrasesList.toArray(
                        new String[moreThanMaxLengthNegativePhrasesList.size()]),
                        JavaOrPerlExpectedResult.both(ExpectedResult.errors(new Notification(5001,
                                Api5ErrorDetails.MINUS_PHRASES_LENGHT_MORE_THAN,
                                CampaignAddItemMap.MAX_NEGATIVE_KEYWORDS_LENGTH)))},
                {"[цветы в горшках", new String[]{"[цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_BRACKETS_IN_MINUS_PHRASE, "[цветы в горшках")))},
                {"цветы+в+горшках", new String[]{"цветы+в+горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_MINUS_PHRASE, "+", "цветы+в+горшках")))},
                {"цветы!в!горшках", new String[]{"цветы!в!горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_MINUS_PHRASE, "!", "цветы!в!горшках")))},
                {"цветы в горшках+", new String[]{"цветы в горшках+"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_MINUS_PHRASE, "+", "цветы в горшках+")))},
                {"цветы в горшках!", new String[]{"цветы в горшках!"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_MINUS_PHRASE, "!", "цветы в горшках!")))},
                {"+ цветы в горшках", new String[]{"+ цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_MINUS_PHRASE, "+", "+ цветы в горшках")))},
                {"++цветы в горшках", new String[]{"++цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_MINUS_PHRASE, "+", "++цветы в горшках")))},
                {"-цветы в горшках", new String[]{"-цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_START_OR_END_OF_MINUS_PHRASE, "-",
                                        "-цветы в горшках")))},
                {"цветы в горшках-", new String[]{"цветы в горшках-"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_START_OR_END_OF_MINUS_PHRASE, "-",
                                        "цветы в горшках-")))},
                {"цветы в горшках-, цветы в горшках", new String[]{"цветы в горшках-", "цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.INCORRECT_USE_OF_SYMBOL_IN_START_OR_END_OF_MINUS_PHRASE, "-",
                                        "цветы в горшках-")))},
                {",цветы в горшках", new String[]{",цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.MINUS_PHRASES_CAN_ONLY_CONSIST, ",цветы в горшках")))},
                {"цветы в горшках, цветы в горшках", new String[]{"цветы в горшках", "цветы в горшках"},
                        JavaOrPerlExpectedResult.both(ExpectedResult.errors(new Notification(9802,
                                Api5ErrorDetails.ELEMENT_PRESENT_IN_LIST_MORE_THAN_ONE_TIME,
                                "цветы в горшках", capitalize(CampaignAddItemMap.NEGATIVE_KEYWORDS))))},
                {"цветы в горшках,", new String[]{"цветы в горшках,"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                Api5ErrorDetails.MINUS_PHRASES_CAN_ONLY_CONSIST, "цветы в горшках,")))},
                {"10.10.10 цветы в горшках", new String[]{"10.10.10 цветы в горшках"},
                        JavaOrPerlExpectedResult
                                .both(ExpectedResult.errors(new Notification(5002,
                                        Api5ErrorDetails.MINUS_PHRASES_CANNOT_CONTAIN_MORE_THAN_TWO_NUMBERS,
                                        "10.10.10 цветы в горшках")))}
        };
        return Arrays.asList(data);
    }

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

    @Test
    public void addWithNegativeKeyPhrases() {
        api.userSteps.campaignSteps().shouldGetResultOnAdd(new AddRequestMap()
                        .withCampaigns(new CampaignAddItemMap()
                                .defaultCampaignAddItem().withNegativeKeywords(negativeKeyPhrases)
                                .withDefaultTextCampaign()
                        ),
                expectedResult);
    }

}
