package ru.yandex.autotests.direct.api.ads.businesses;

import com.yandex.direct.api.v5.businesses.BusinessFieldEnum;
import com.yandex.direct.api.v5.businesses.BusinessGetItem;
import com.yandex.direct.api.v5.businesses.GetResponse;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.api.ads.AdsLogins;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.apiclient.errors.Api5Error;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetailsJava;
import ru.yandex.autotests.directapi.model.api5.businesses.BusinessesGetItemMap;
import ru.yandex.autotests.directapi.model.api5.businesses.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.general.IdsCriteriaMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.steps.businesses.BusinessesSteps;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static ru.yandex.autotests.directapi.apiclient.errors.Path.path;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

@Aqua.Test
@Features(BusinessesFeatures.GET)
@Description("Проверка получения организаций из Справочника")
public class BusinessesGetTest {
    /**
     * Клиент для теста, менять только вместе с пермалинками ниже.
     */
    private static final String CLIENT = AdsLogins.CLIENT;
    /**
     * Пермалинки, владельцем которых является указанный выше клиент. Менять только в связке со Cправочником
     */
    private static final long ACCESSIBLE_PERMALINK_ID = 139661595675L;
    private static final long SECOND_ACCESSIBLE_PERMALINK_ID = 36494752047L;
    private static final long INACCESSIBLE_PERMALINK_ID = 1208146729L;

    private BusinessesSteps businessesSteps;

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

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

    @Before
    public void before() {
        businessesSteps = api.userSteps.businessesSteps();
        long clientId = api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT).shardingSteps()
                .getClientIdByLogin(CLIENT);
        api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT).organizationsSteps()
                .createFakeClientOrganization(clientId, INACCESSIBLE_PERMALINK_ID);
    }

    @Test
    @Description("Получение всех организаций клиента")
    public void getBusinessesWithoutSelectionCriteria() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withFieldNames(BusinessFieldEnum.ID);
        GetResponse getResponse = businessesSteps.businessesGet(CLIENT, getRequestMap);

        assertThat("Получены все доступные пермалинки клиента", getResponse.getBusinesses(),
                containsInAnyOrder(new BusinessesGetItemMap().withId(ACCESSIBLE_PERMALINK_ID).getBean(),
                        new BusinessesGetItemMap().withId(SECOND_ACCESSIBLE_PERMALINK_ID).getBean(),
                        new BusinessesGetItemMap().withId(INACCESSIBLE_PERMALINK_ID).getBean()));
    }

    @Test
    @Description("Получение организации, принадлежащей клиенту")
    public void getBusinessesWithOneOrganization() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap().withIds(ACCESSIBLE_PERMALINK_ID))
                .withFieldNames(BusinessFieldEnum.ID);
        GetResponse getResponse = businessesSteps.businessesGet(CLIENT, getRequestMap);

        assertThat("Получена запрошенная организация", getResponse.getBusinesses(),
                containsInAnyOrder(new BusinessesGetItemMap()
                        .withId(ACCESSIBLE_PERMALINK_ID)
                        .getBean()));
    }

    @Test
    @Description("Получение организации, не принадлежащей клиенту")
    public void getBusinessesWithNotOwnedOrganization() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap().withIds(ACCESSIBLE_PERMALINK_ID + 1))
                .withFieldNames(BusinessFieldEnum.ID);
        GetResponse getResponse = businessesSteps.businessesGet(CLIENT, getRequestMap);

        assertThat("Ничего не получено", getResponse.getBusinesses(), hasSize(0));
    }

    @Test
    @Description("Получение организации, которая принадлежала раньше клиенту, но больше не принадлежит")
    public void getBusinessesWithPreviouslyOwnedOrganization() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap().withIds(INACCESSIBLE_PERMALINK_ID))
                .withFieldNames(BusinessFieldEnum.ID);
        GetResponse getResponse = businessesSteps.businessesGet(CLIENT, getRequestMap);

        assertThat("Получена запрошенная организация", getResponse.getBusinesses(),
                containsInAnyOrder(new BusinessesGetItemMap()
                        .withId(INACCESSIBLE_PERMALINK_ID)
                        .getBean()));
    }

    @Test
    @Description("Получение всех полей организации")
    public void getBusinessesWithAllFields() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap().withIds(ACCESSIBLE_PERMALINK_ID))
                .withFieldNames(BusinessFieldEnum.values());
        GetResponse getResponse = businessesSteps.businessesGet(CLIENT, getRequestMap);

        assertThat("Получена одна организация", getResponse.getBusinesses(), hasSize(1));

        BusinessGetItem responseItem = getResponse.getBusinesses().get(0);
        assertThat("Получено Id организации", responseItem.getId(), notNullValue());
        assertThat("Получено название организации", responseItem.getName(), notNullValue());
        assertThat("Получен адрес организации", responseItem.getAddress(), notNullValue());
        assertThat("Получен телефон организации", responseItem.getPhone(), notNullValue());
        assertThat("Получена ссылка на профиль организации", responseItem.getProfileUrl(), notNullValue());
        assertThat("Получена ссылка на страницу редактирования организации", responseItem.getInternalUrl(), notNullValue());
        assertThat("Получен статус публикации организации", responseItem.getIsPublished(), notNullValue());
        assertThat("Получен список склеенных пермалинков", responseItem.getMergedIds(), notNullValue());
        assertThat("Получен список склеенных пермалинков", responseItem.getRubric(), notNullValue());
        assertThat("Получен список склеенных пермалинков", responseItem.getUrls(), notNullValue());
        assertThat("Получен список склеенных пермалинков", responseItem.getHasOffice(), notNullValue());
    }

    @Test
    @Description("Ошибка при запросе с пустым SelectionCriteria")
    public void getBusinessesWithEmptySelectionCriteria_Error() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap())
                .withFieldNames(BusinessFieldEnum.ID);
        businessesSteps.shouldGetResultOnGet(CLIENT, getRequestMap,
                new Api5Error(8000, Api5ErrorDetailsJava.MISSING_PARAMETER_VALUE,
                        path(IdsCriteriaMap.IDS)));
    }

    @Test
    @Description("Ошибка при запросе с отсутствующим FieldNames")
    public void getBusinessesWithoutFieldNames_Error() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap().withIds(ACCESSIBLE_PERMALINK_ID));
        businessesSteps.shouldGetResultOnGet(CLIENT, getRequestMap,
                new Api5Error(8000, Api5ErrorDetailsJava.MISSING_PARAMETER_VALUE,
                        path(GetRequestMap.FIELD_NAMES)));
    }

    @Test
    @Description("Ошибка при запросе с пустым FieldNames")
    public void getBusinessesWithEmptyFieldNames_Error() {
        GetRequestMap getRequestMap = new GetRequestMap()
                .withSelectionCriteria(new IdsCriteriaMap().withIds(ACCESSIBLE_PERMALINK_ID))
                .withFieldNames();
        businessesSteps.shouldGetResultOnGet(CLIENT, getRequestMap,
                new Api5Error(8000, Api5ErrorDetailsJava.FIELD_MUST_CONTAIN_NOT_LESS_ELEMENTS,
                        path(GetRequestMap.FIELD_NAMES), 1));
    }
}
