package ru.yandex.autotests.directapi.clients.update;

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

import org.junit.Before;
import org.junit.ClassRule;
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.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.clients.ClientsFeatures;
import ru.yandex.autotests.directapi.clients.ClientsLogins;
import ru.yandex.autotests.directapi.model.api5.clients.ClientUpdateItemMap;
import ru.yandex.autotests.directapi.model.api5.clients.UpdateRequestMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
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.allure.annotations.Step;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

/**
 * https://st.yandex-team.ru/DIRECT-64582
 */
@Aqua.Test
@Features(ClientsFeatures.UPDATE)
@Issue("https://st.yandex-team.ru/DIRECT-62304")
@Description("Проверка прав доступа, негативные сценарии")
@RunWith(Parameterized.class)
public class CheckRightsNegativeTest {
    @ClassRule
    public static ApiSteps api = new ApiSteps();

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

    @Parameterized.Parameter(0)
    public String description;

    @Parameterized.Parameter(1)
    public String operatorLogin;

    @Parameterized.Parameter(2)
    public String clientLogin;

    @Parameterized.Parameter(3)
    public Api5Error expectedError;

    @Parameterized.Parameters(name = "{0} (operatorLogin = {1}, clientLogin = {2}, expectedErrorDetail = {3})")
    public static Collection<Object[]> testData() {
        return Arrays.asList(new Object[][]{
                {"Запрос без Client-Login выдаёт ошибку для роли MANAGER",
                        ClientsLogins.MANAGER_DEFAULT, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Запрос без Client-Login выдаёт ошибку для роли AGENCY",
                        ClientsLogins.LOGIN_AGENCY, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Запрос без Client-Login выдаёт ошибку для роли MEDIA",
                        ClientsLogins.MEDIA, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Запрос без Client-Login выдаёт ошибку для роли PLACER",
                        ClientsLogins.PLACER, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Запрос без Client-Login выдаёт ошибку для роли SUPER",
                        ClientsLogins.SUPER_LOGIN, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Запрос без Client-Login выдаёт ошибку для роли SUPER_READER",
                        ClientsLogins.SUPER_READER, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Запрос без Client-Login выдаёт ошибку для роли SUPPORT",
                        ClientsLogins.SUPPORT, null, error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},

                {"Пользователь не может менять данные произвольного пользователя",
                        ClientsLogins.SINGLE_CLIENT_RUB, ClientsLogins.CLIENT_FREE_YE_DEFAULT_REP_2,
                        error(8800, Api5ErrorDetails.UNKNOWN_LOGIN_IN_CLIENT_LOGIN)},

                {"Не главный представитель клиента не может менять данные главного",
                        ClientsLogins.CLIENT_FREE_YE_DEFAULT_REP_2, ClientsLogins.CLIENT_FREE_YE_DEFAULT,
                        error(54, Api5ErrorDetails.NO_RIGHTS_TO_THIS_USER)},
                {"Не главный представитель клиента не может менять данные другого не главного",
                        ClientsLogins.CLIENT_FREE_YE_DEFAULT_REP_2, ClientsLogins.CLIENT_FREE_YE_DEFAULT_REP,
                        error(54, Api5ErrorDetails.NO_RIGHTS_TO_THIS_USER)},

                {"Представитель агенства не может менять данные произвольного пользователя",
                        ClientsLogins.AGENCY_YE_DEFAULT, ClientsLogins.SINGLE_CLIENT_RUB,
                        error(8800, Api5ErrorDetails.UNKNOWN_LOGIN_IN_CLIENT_LOGIN)},
                {"Представитель агенства не может менять данные не принадлежаещего ему субклиента",
                        ClientsLogins.AGENCY_YE_DEFAULT, ClientsLogins.LOGIN_SUBCLIENT,
                        error(8800, Api5ErrorDetails.UNKNOWN_LOGIN_IN_CLIENT_LOGIN)},
                {"Представитель агенства не может менять данные своего субклиента",
                        ClientsLogins.LOGIN_AGENCY, ClientsLogins.LOGIN_SUBCLIENT,
                        error(54, Api5ErrorDetails.EMPTY_STRING)},

                {"Главный представитель агенства не может менять данные не главного",
                        ClientsLogins.AGENCY_YE_DEFAULT, ClientsLogins.AGENCY_YE_DEFAULT_REP,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Главный представитель агенства не может менять свои данные",
                        ClientsLogins.AGENCY_YE_DEFAULT, ClientsLogins.AGENCY_YE_DEFAULT,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Не главный представитель агенства не может менять данные другого не главного",
                        ClientsLogins.AGENCY_YE_DEFAULT_REP, ClientsLogins.AGENCY_YE_DEFAULT_REP_2,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Не главный представитель агенства не может менять свои данные",
                        ClientsLogins.AGENCY_YE_DEFAULT_REP, ClientsLogins.AGENCY_YE_DEFAULT_REP,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},

                {"Пользователь с ролью PLACER не может пользоваться этим сервисом",
                        ClientsLogins.PLACER, ClientsLogins.LOGIN_FOR_RUB,
                        error(54, Api5ErrorDetails.EMPTY_STRING)},
                {"Пользователь с ролью MEDIA не может пользоваться этим сервисом",
                        ClientsLogins.MEDIA, ClientsLogins.LOGIN_FOR_RUB,
                        error(54, Api5ErrorDetails.EMPTY_STRING)},
                {"Пользователь с ролью SUPER_READER не может пользоваться этим сервисом",
                        ClientsLogins.SUPER_READER, ClientsLogins.LOGIN_FOR_RUB,
                        error(54, Api5ErrorDetails.EMPTY_STRING)},

                {"Нельзя менять пользователей с внутренними ролями",
                        ClientsLogins.SUPER_LOGIN, ClientsLogins.MANAGER_DEFAULT,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Нельзя менять пользователей с внутренними ролями",
                        ClientsLogins.SUPER_LOGIN, ClientsLogins.SUPER_LOGIN,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Нельзя менять пользователей с внутренними ролями",
                        ClientsLogins.SUPER_LOGIN, ClientsLogins.MEDIA,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Нельзя менять пользователей с внутренними ролями",
                        ClientsLogins.SUPER_LOGIN, ClientsLogins.PLACER,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Нельзя менять пользователей с внутренними ролями",
                        ClientsLogins.SUPER_LOGIN, ClientsLogins.SUPER_READER,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
                {"Нельзя менять пользователей с внутренними ролями",
                        ClientsLogins.SUPER_LOGIN, ClientsLogins.SUPPORT,
                        error(8000, Api5ErrorDetailsJava.NOT_CLIENT_IN_CLIENT_LOGIN)},
        });
    }

    @Before
    @Step("Подготовка тестовых данных")
    public void clear() {
        api.as(operatorLogin);
    }

    @Test
    public void rolesTest() {
        api.userSteps.clientsStepsV5().expectErrorOnClientsUpdate(
                new UpdateRequestMap().withClients(new ClientUpdateItemMap()), clientLogin, expectedError);
    }

    private static Api5Error error(int code, Api5ErrorDetails detail) {
        return new Api5Error(code, detail);
    }
    private static Api5Error error(int code, Api5ErrorDetailsJava detail) {
        return new Api5Error(code, detail);
    }
}
