package ru.yandex.autotests.directapi.keywords.add.keyword;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;
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.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetails;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetailsJava;
import ru.yandex.autotests.directapi.keywords.KeywordsFeatures;
import ru.yandex.autotests.directapi.keywords.KeywordsLogins;
import ru.yandex.autotests.directapi.model.api5.Action;
import ru.yandex.autotests.directapi.model.api5.general.ExpectedResult;
import ru.yandex.autotests.directapi.model.api5.general.Notification;
import ru.yandex.autotests.directapi.model.api5.keywords.AddRequestMap;
import ru.yandex.autotests.directapi.model.api5.keywords.KeywordAddMap;
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.hazelcast.SemaphoreRule;

import static org.apache.commons.lang3.StringUtils.capitalize;

/**
 * Created by chicos on 15.03.2015.
 */
@Aqua.Test
@Features(KeywordsFeatures.ADD)
@Description("Проверка добавления различных значений параметра Keyword")
@Tag(TagDictionary.TRUNK)
@RunWith(Parameterized.class)
public class AddKeywordsKeywordTest {
    private static final String client = KeywordsLogins.SINGLE_CLIENT_ADD;
    private static Long campaignID;

    private long groupID;

    private static final String KEYWORD_WITH_EXCLAMATION = "! Шостакович";
    private static final String KEYWORD_WITH_PLUS_SIGN = "портальные + краны";

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

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

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

    @Parameterized.Parameter(value = 0)
    public String description;

    @Parameterized.Parameter(value = 1)
    public List<String> keywordValues;

    @Parameterized.Parameter(value = 2)
    public ExpectedResult expectedResult;

    @Parameterized.Parameters(name = "test = {0}")
    public static Collection fields() {
        String badEncoding = new String("Параметр".getBytes(Charset.forName("UTF-8")), Charset.forName("cp1251"));
        Object[][] data = new Object[][]{
                {"Пустая строка", Collections.singletonList(""),
                        ExpectedResult.errors(
                                new Notification(5000, Api5ErrorDetails.NO_VALUE_IN_FIELD,
                                        capitalize(KeywordAddMap.KEYWORD)))},
                {"Строка из пробела", Collections.singletonList(" "),
                        ExpectedResult.errors(new Notification(5000, Api5ErrorDetails.NO_VALUE_IN_FIELD,
                                capitalize(KeywordAddMap.KEYWORD)))},
                {"Латинские символы", Collections.singletonList("window"),
                        ExpectedResult.success()},
                {"Кириллические символы", Collections.singletonList("проездной"),
                        ExpectedResult.success()},
                {"Турецкие символы", Collections.singletonList("müthişreklamÇĞğÖŞÜ"),
                        ExpectedResult.success()},
                {"Белорусские символы", Collections.singletonList("аплата наяўнымі"),
                        ExpectedResult.success()},
                {"Цифровые символы", Collections.singletonList(RandomStringUtils.randomNumeric(10)),
                        ExpectedResult.success()},
                {"Латинские и цифровые символы", Collections.singletonList(RandomStringUtils.randomAlphanumeric(10)),
                        ExpectedResult.success()},
                {"Ключевое заканчивается символом .", Collections.singletonList("кирпич."),
                        ExpectedResult.success()},
                {"Ключевое начинается с символа .", Collections.singletonList(".Net"),
                        ExpectedResult.errors(new Notification(5161,
                                Api5ErrorDetails.MINUS_PHRASES_COULD_NOT_START_WITH_DOT_OR_APOSTROPHE, "\".Net\""))},
                {"Использование символа '", Collections.singletonList("rock'n'roll детка"),
                        ExpectedResult.success()},
                {"Ключевое начинается с символа '", Collections.singletonList("'window"),
                        ExpectedResult.errors(new Notification(5161,
                                Api5ErrorDetails.MINUS_PHRASES_COULD_NOT_START_WITH_DOT_OR_APOSTROPHE,
                                "\"'window\""))},
                {"Ключевое заканчивается символом '", Collections.singletonList("window'"),
                        ExpectedResult.success()},
                {"Ключевое состоящее из более 7 слов", Collections.singletonList(
                        "неожиданные структурные перекосы экономически опосредованной объективной реальности России"),
                        ExpectedResult.errors(
                                new Notification(5140, Api5ErrorDetails.KEYWORD_COULD_NOT_CONTAIN_MORE_WORDS,
                                        "неожиданные структурные перекосы экономически опосредованной объективной реальности России"))},
                {"Ключевое состоящее из более 7 слов со стоп-словом", Collections.singletonList(
                        "\"неожиданные структурные перекосы экономически опосредованной объективной реальности вас\""),
                        ExpectedResult.errors(new Notification(5140,
                                Api5ErrorDetails.KEYWORD_COULD_NOT_CONTAIN_MORE_WORDS,
                                "\"неожиданные структурные перекосы экономически опосредованной объективной реальности вас\""))},
                {"Пробелы в начале и конце", Collections.singletonList("    рефераты "),
                        ExpectedResult.success()},
                {"Пробел в середине", Collections.singletonList("пластиковые  окна"),
                        ExpectedResult.success()},
                {"Ключевое из стоп-слова с символом 'ё'", Collections.singletonList("всё"),
                        ExpectedResult.errors(
                                new Notification(5141,
                                        Api5ErrorDetails.KEYWORD_COULD_NOT_CONSIST_OF_STOPWORDS_ONLY, "все"))},
                {"Ключевое содержит стоп-слово", Collections.singletonList("мир всем"),
                        ExpectedResult.success()},
                {"Ключевое из стоп-слов", Collections.singletonList("все мне"),
                        ExpectedResult.errors(new Notification(5141,
                                Api5ErrorDetails.KEYWORD_COULD_NOT_CONSIST_OF_STOPWORDS_ONLY, "все мне"))},
                {"Использование стоп-слов", Collections.singletonList("товары +для автомобиля"),
                        ExpectedResult.success()},
                {"Фиксация словоформы одиночное", Collections.singletonList("!искусный"),
                        ExpectedResult.success()},
                {"Фиксация словоформы несколько", Collections.singletonList("макияж !трафарет "),
                        ExpectedResult.success()},
                {"С учётом словоформ одиночное", Collections.singletonList("\"влюбленный\""),
                        ExpectedResult.success()},
                {"C учётом словоформ несколько", Collections.singletonList("\"котята шредингера купить\""),
                        ExpectedResult.success()},
                {"С учетом словоформ и фиксацией", Collections.singletonList("\"!пенобетон\""),
                        ExpectedResult.success()},
                {"C учётом словоформ и стоп-слов", Collections.singletonList("\"решетка +для камина\""),
                        ExpectedResult.success()},
                {"C учётом словоформ лишние кавычки", Collections.singletonList("\"омывающая жидкость\"\""),
                        ExpectedResult.errors(new Notification(5002,
                                Api5ErrorDetails.KEYWORD_INCORRECT_USAGE_OF_QUOTES, "\"омывающая жидкость\"\""))},
                {"Использование группировки", Collections.singletonList("ремонт (автомобилей | машин)"),
                        ExpectedResult.errors(new Notification(5002,
                                Api5ErrorDetails.INVALID_KEYWORD_SYMBOLS, "ремонт (автомобилей | машин)"))},
                {"Добавление уже существующего слова",
                        Arrays.asList("гарантийный ремонт каминов", "гарантийный ремонт каминов"),
                        ExpectedResult.warnings(new Notification(10140))},
                //DIRECT-41856
                /*{"С учётом словоформ некорректное", Arrays.asList("котята \"шредингера купить\""),
                        ExpectedResult.errors(new Notification(5002, Api5ErrorDetails.KEYWORD_INCORRECT_USAGE_OF_QUOTES, "котята \"шредингера купить\""))},*/
                //DIRECT-41857 DIRECT-79517
                {"Некорректное использование символа !", Collections.singletonList(KEYWORD_WITH_EXCLAMATION),
                        ExpectedResult.errors(new Notification(5002,
                                Api5ErrorDetailsJava.INCORRECT_USE_OF_SYMBOL_IN_KEYWORD,
                                KEYWORD_WITH_EXCLAMATION, "!"))},
                {"Некорректное использование символа +", Collections.singletonList(KEYWORD_WITH_PLUS_SIGN),
                        ExpectedResult.errors(new Notification(5002,
                                Api5ErrorDetailsJava.INCORRECT_USE_OF_SYMBOL_IN_KEYWORD,
                                KEYWORD_WITH_PLUS_SIGN, "+"))},
                //DIRECT-43093
                /*{"Кодировка UTF-8 как CP1251", Arrays.asList(badEncoding),
                        ExpectedResult.errors(new Notification(5002, Api5ErrorDetails.INVALID_KEYWORD_SYMBOLS, badEncoding))}*/
        };
        return Arrays.asList(data);
    }

    @BeforeClass
    public static void createCampaign() {
        campaignID = api.userSteps.campaignSteps().addDefaultTextCampaign(client);
    }

    @Before
    public void prepareGroup() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        groupID = api.userSteps.adGroupsSteps().addDefaultGroup(campaignID);
        //добавим ключевые слова из набора, кроме последнего слова
        for (int i = 0; i < keywordValues.size() - 1; i++) {
            api.userSteps.keywordsSteps().addKeyword(groupID, keywordValues.get(i));
        }
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("3587")
    public void keywordsTest() {
        String lastWord = keywordValues.get(keywordValues.size() - 1);
        api.userSteps.keywordsSteps().shouldGetResultOn(
                Action.ADD,
                new AddRequestMap().withKeywords(new KeywordAddMap()
                        .withAdGroupId(groupID)
                        .withKeyword(lastWord)),
                expectedResult);
    }

    /*
    @Test
    public void keywordsTestOld() {
        String lastWord = keywordValues.get(keywordValues.size() - 1);
        api.userSteps.bannerSteps().createBanner(new BannerInfoMap(api.type())
                .defaultBanner()
                .withCampaignID(campaignID)
                .withPhrases(new BannerPhraseInfoMap(api.type())
                        .withTextPhrase(lastWord)
                        .withPrice(0.01f)));
    }
    */
}
