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

import com.yandex.direct.api.v5.sitelinks.SitelinksSetFieldEnum;
import org.json.simple.JSONObject;
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.directapi.ApiStories;
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.apiclient.errors.Api5ErrorDetailsJava;
import ru.yandex.autotests.directapi.model.api5.general.IdsCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.general.LimitOffsetMap;
import ru.yandex.autotests.directapi.model.api5.sitelinks.GetRequestMap;
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.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.directapi.apiclient.errors.Path.path;

/**
 * Created by semkagtn on 2/9/15.
 * https://st.yandex-team.ru/TESTIRT-4099
 */
@Aqua.Test
@Features(SitelinksFeatures.GET)
@Stories(ApiStories.JSON5)
@Description("Валидация JSON-запроса для получения наборов сайтлинков")
public class GetJsonValidationTest {

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

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

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

    @Before
    public void addUnitsToUser() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(SitelinksLogins.CLIENT);
    }

    @Test
    @Description("Массив в поле SelectionCriteria")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3881")
    public void arrayInSelectionCriteriaField() {
        JSONObject request = new JSONObject();
        Object selectionCriteria = new IdsCriteriaMap()
                .withIds(0L).getBean();
        request.put(path(GetRequestMap.SELECTION_CRITERIA), new Object[]{selectionCriteria});
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_NOT_CONTAIN_ARRAY,
                        path(GetRequestMap.SELECTION_CRITERIA)));
    }

    @Test
    @Description("Не массив в поле SelectionCriteria.Ids")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3884")
    public void notAnArrayInIdsFields() {
        JSONObject request = new JSONObject();
        JSONObject selectionCriteria = new JSONObject();
        selectionCriteria.put(path(IdsCriteriaMap.IDS), 0L);
        request.put(path(GetRequestMap.SELECTION_CRITERIA), selectionCriteria);
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_CONTAIN_ARRAY,
                        path(GetRequestMap.SELECTION_CRITERIA, IdsCriteriaMap.IDS)));
    }

    @Test
    @Description("Строка внутри массива SelectionCriteria.Ids")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3882")
    public void stringInIdsArray() {
        String value = "SomeInvalidValue";
        JSONObject request = new JSONObject();
        JSONObject selectionCriteria = new JSONObject();
        selectionCriteria.put(path(IdsCriteriaMap.IDS), new String[]{value});
        request.put(path(GetRequestMap.SELECTION_CRITERIA), selectionCriteria);
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.ELEMENT_OF_ARRAY_MUST_CONTAIN_INTEGER_VALUE,
                        path(GetRequestMap.SELECTION_CRITERIA, IdsCriteriaMap.IDS)));
    }

    @Test
    @Description("Массив внутри массива SelectionCriteria.Ids")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3883")
    public void arrayInIdsArray() {
        JSONObject request = new JSONObject();
        JSONObject selectionCriteria = new JSONObject();
        selectionCriteria.put(path(IdsCriteriaMap.IDS), new Long[][]{new Long[]{0L}});
        request.put(path(GetRequestMap.SELECTION_CRITERIA), selectionCriteria);
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.ELEMENT_OF_ARRAY_MUST_CONTAIN_INTEGER_VALUE,
                        path(GetRequestMap.SELECTION_CRITERIA, IdsCriteriaMap.IDS)));
    }

    @Test
    @Description("Массив в поле Page")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3885")
    public void arrayInPageField() {
        JSONObject request = new JSONObject();
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        Object limitOffset = new LimitOffsetMap()
                .withLimit(0L)
                .withOffset(0L).getBean();
        request.put(path(GetRequestMap.PAGE), new Object[]{limitOffset});
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_NOT_CONTAIN_ARRAY, path(GetRequestMap.PAGE)));
    }

    @Test
    @Description("Массив в поле Page.Limit")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3886")
    public void arrayInLimitField() {
        JSONObject request = new JSONObject();
        JSONObject limitOffset = new JSONObject();
        limitOffset.put(path(LimitOffsetMap.LIMIT), new Long[]{0L});
        limitOffset.put(path(LimitOffsetMap.OFFSET), 0L);
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        request.put(path(GetRequestMap.PAGE), limitOffset);
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_NOT_CONTAIN_ARRAY,
                        path(GetRequestMap.PAGE, LimitOffsetMap.LIMIT)));
    }

    @Test
    @Description("Строка в поле Page.Limit")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3887")
    public void stringInLimitField() {
        String value = "StringValue";
        JSONObject request = new JSONObject();
        JSONObject limitOffset = new JSONObject();
        limitOffset.put(path(LimitOffsetMap.LIMIT), value);
        limitOffset.put(path(LimitOffsetMap.OFFSET), 0L);
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        request.put(path(GetRequestMap.PAGE), limitOffset);
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_CONTAIN_INTEGER_VALUE,
                        path(GetRequestMap.PAGE, LimitOffsetMap.LIMIT)));
    }

    @Test
    @Description("Массив в поле Page.Offset")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3888")
    public void arrayInOffsetField() {
        JSONObject request = new JSONObject();
        JSONObject limitOffset = new JSONObject();
        limitOffset.put(path(LimitOffsetMap.LIMIT), 0L);
        limitOffset.put(path(LimitOffsetMap.OFFSET), new Long[]{0L});
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        request.put(path(GetRequestMap.PAGE), limitOffset);
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_NOT_CONTAIN_ARRAY,
                        path(GetRequestMap.PAGE, LimitOffsetMap.OFFSET)));
    }

    @Test
    @Description("Строка в поле Page.Offset")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3889")
    public void stringInOffsetField() {
        String value = "StringValue";
        JSONObject request = new JSONObject();
        JSONObject limitOffset = new JSONObject();
        limitOffset.put(path(LimitOffsetMap.LIMIT), 0L);
        limitOffset.put(path(LimitOffsetMap.OFFSET), value);
        request.put(path(GetRequestMap.FIELD_NAMES), new String[]{SitelinksSetFieldEnum.ID.value()});
        request.put(path(GetRequestMap.PAGE), limitOffset);
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_CONTAIN_INTEGER_VALUE,
                        path(GetRequestMap.PAGE, LimitOffsetMap.OFFSET)));
    }

    @Test
    @Description("Не массив в поле FieldNames")
    @ru.yandex.qatools.allure.annotations.TestCaseId("3890")
    public void notAnArrayInFieldNamesField() {
        JSONObject request = new JSONObject();
        request.put(path(GetRequestMap.FIELD_NAMES), SitelinksSetFieldEnum.ID.value());
        api.userSteps.sitelinksSteps().expectErrorOnGet(request,
                new Api5Error(8000, Api5ErrorDetails.FIELD_MUST_CONTAIN_ARRAY, path(GetRequestMap.FIELD_NAMES)));
    }
}
