package ru.yandex.autotests.directapi.sitelinks.add;

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

import com.yandex.direct.api.v5.sitelinks.SitelinksSetGetItem;
import org.junit.Before;
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.model.api5.general.ExpectedResult;
import ru.yandex.autotests.directapi.model.api5.sitelinks.AddRequestMap;
import ru.yandex.autotests.directapi.model.api5.sitelinks.SitelinkGetMap;
import ru.yandex.autotests.directapi.model.api5.sitelinks.SitelinkMap;
import ru.yandex.autotests.directapi.model.api5.sitelinks.SitelinksSetAddItemMap;
import ru.yandex.autotests.directapi.model.api5.sitelinks.SitelinksSetGetItemMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.sitelinks.SitelinksFeatures;
import ru.yandex.autotests.directapi.sitelinks.SitelinksLogins;
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.RandomStringUtils.randomAlphabetic;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;
import static ru.yandex.autotests.irt.testutils.beandiffer.BeanDifferMatcher.beanEquivalent;

/**
 * Created by semkagtn on 2/3/15.
 * https://st.yandex-team.ru/TESTIRT-4100
 */
@Aqua.Test
@Features(SitelinksFeatures.ADD)
@Description("Валидация ссылки в сайтлинках: позитивные сценарии")
@Tag(TagDictionary.TRUNK)
@RunWith(Parameterized.class)
public class AddHrefValidationTest {

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

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

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

    private AddRequestMap addRequestMap;

    @Parameterized.Parameter(0)
    public String description;

    @Parameterized.Parameter(1)
    public String href;

    @Parameterized.Parameter(2)
    public String expectedHref;

    @Parameterized.Parameters(name = "{0}")
    public static Collection<Object[]> data() {
        String httpHref = "http://yandex.ru";
        String httpsHref = "https://ya.ru";
        String minDomainLengthHref = "http://" + randomAlphabetic(SitelinkMap.MIN_DOMAIN_LENGTH) + ".ru";
        String maxDomainLengthHref = "http://" + randomAlphabetic(SitelinkMap.MAX_DOMAIN_LENGTH) +
                "." + randomAlphabetic(SitelinkMap.MAX_DOMAIN_LENGTH) + ".ru";
        String minTopDomainLengthHref = "http://test." + "ru";
        String maxTopDomainLengthHref = "http://tester." + "weatherchannel";
        String russianHref = "http://подарки.рф";
        String ukrainianHref = "http://сувеніри.укр";
        String numericHref = "http://12345.com";
        String dashedHref = "http://hello-world.ru";
        String maxLengthHref = "http://" + generateValidHrefWithoutProtocolOfLength(SitelinkMap.MAX_HREF_LENGTH - 7);

        return Arrays.asList(new Object[][]{
                {"Создать сайтлинк со ссылкой, протокол которой http", httpHref, httpHref},
                {"Создать сайтлинк со ссылкой, протокол которой https", httpsHref, httpsHref},
                {"Создать сайтлинк со ссылкой с внутренним доменом длиной " + SitelinkMap.MIN_DOMAIN_LENGTH,
                        minDomainLengthHref, minDomainLengthHref},
                {"Создать сайтлинк со ссылкой с внутренними доменами длиной " + SitelinkMap.MAX_DOMAIN_LENGTH,
                        maxDomainLengthHref, maxDomainLengthHref},
                {"Создать сайтлинк со ссылкой с доменом верхнего уровня длиной " + SitelinkMap.MIN_TOP_DOMAIN_LENGTH,
                        minTopDomainLengthHref, minTopDomainLengthHref},
                {"Создать сайтлинк со ссылкой с доменом верхнего уровня длиной " + SitelinkMap.MAX_TOP_DOMAIN_LENGTH,
                        maxTopDomainLengthHref, maxTopDomainLengthHref},
                {"Создать сайтлинк со ссылкой, состоящей из русских букв", russianHref, russianHref},
                {"Создать сайтлинк со ссылкой, состоящей из украинских букв", ukrainianHref, ukrainianHref},
                {"Создать сайтлинк со ссылкой, содержащей цифры", numericHref, numericHref},
                {"Создать сайтлинк со ссылкой, содержащей дефисы", dashedHref, dashedHref},
                {"Создать сайтлинк со ссылкой, длиной " + SitelinkMap.MAX_HREF_LENGTH, maxLengthHref, maxLengthHref}
        });
    }

    @Before
    public void initAddRequestMap() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(SitelinksLogins.CLIENT);
        addRequestMap = new AddRequestMap()
                .withSitelinksSets(new SitelinksSetAddItemMap()
                        .withSitelinks(new SitelinkMap()
                                .withRandomTitle()
                                .withHref(href)));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("3792")
    public void addSitelinkWithSpecificHrefResponse() {
        api.userSteps.sitelinksSteps().shouldGetResultOnAdd(addRequestMap, ExpectedResult.success());
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("3793")
    public void addSitelinkWithSpecificHrefSave() {
        List<Long> ids = api.userSteps.sitelinksSteps().add(addRequestMap);
        assumeThat("создался один набор сайтлинков", ids, hasSize(1));
        List<SitelinksSetGetItem> result = api.userSteps.sitelinksSteps().get(ids);
        assertThat("ссылка сайтлинка сохранилась верно", result, beanEquivalent(Arrays.asList(
                (SitelinksSetGetItem) new SitelinksSetGetItemMap()
                        .withSitelinks(new SitelinkGetMap()
                                .withHref(expectedHref)).getBean())));
    }

    private static String generateValidHrefWithoutProtocolOfLength(int length) {
        StringBuilder stringBuilder = new StringBuilder(randomAlphabetic(length));
        int domainLength = Math.min(
                (SitelinkMap.MAX_DOMAIN_LENGTH - 1) / 2, (SitelinkMap.MAX_TOP_DOMAIN_LENGTH - 1) / 2);
        for (int i = domainLength; i < length - domainLength; i += domainLength) {
            if (i == domainLength) {
                stringBuilder.replace(i, i + 4, ".ru/");
            } else {
                stringBuilder.setCharAt(i, '/');
            }
        }
        return stringBuilder.toString();
    }
}
