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

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

import com.yandex.direct.api.v5.clients.ClientFieldEnum;
import com.yandex.direct.api.v5.clients.GetResponse;
import com.yandex.direct.api.v5.general.YesNoEnum;
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.db.models.jooq.ppc.enums.AgencyClientRelationsBind;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.AgencyClientRelationsClientArchived;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.ClientsAllowCreateScampBySubclient;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.UsersStatusarch;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.AgencyClientRelationsRecord;
import ru.yandex.autotests.direct.db.steps.AgencyClientRelationsSteps;
import ru.yandex.autotests.direct.db.steps.ClientsSteps;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.direct.db.steps.UsersSteps;
import ru.yandex.autotests.directapi.clients.ClientsFeatures;
import ru.yandex.autotests.directapi.clients.ClientsLogins;
import ru.yandex.autotests.directapi.darkside.connection.Semaphore;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.clients.GetRequestMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
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.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.equalTo;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

/**
 * Created by alexteut on 16.09.16.
 * https://st.yandex-team.ru/TESTIRT-10268
 */
@Aqua.Test
@Features(ClientsFeatures.GET)
@Issue("https://st.yandex-team.ru/DIRECT-57683")
@Description("Проверки обновления поля Archived")
@RunWith(Parameterized.class)
public class GetArchivedStatusTest {
    @Rule
    public Trashman trasher = new Trashman(api);

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

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

    @Parameterized.Parameter(0)
    public String comment;

    @Parameterized.Parameter(1)
    public String clientLogin;

    @Parameterized.Parameter(2)
    public UsersStatusarch usersStatusarch;

    @Parameterized.Parameter(3)
    public ClientsAllowCreateScampBySubclient clientsAllowCreateScamp;

    @Parameterized.Parameter(4)
    public Object[][] agenciesData;

    @Parameterized.Parameter(5)
    public YesNoEnum isArchived;

    @Parameterized.Parameters(name = "Логин - {1}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {
                        "статус архивации для клиента определён верно",
                        ClientsLogins.LOGIN_ARCHIVED_SINGLE,
                        UsersStatusarch.Yes,
                        ClientsAllowCreateScampBySubclient.No,
                        new Object[][]{},
                        YesNoEnum.YES
                },
                {
                        "статус архивации для субклиента определён верно",
                        ClientsLogins.LOGIN_ARCHIVED_IN_AGENCY,
                        UsersStatusarch.No,
                        ClientsAllowCreateScampBySubclient.No,
                        new Object[][]{
                                {
                                        ClientsLogins.AGENCY_SH2,
                                        AgencyClientRelationsClientArchived.Yes,
                                        AgencyClientRelationsBind.Yes
                                }
                        },
                        YesNoEnum.NO
                },

                {
                        "статус архивации для свободного субклиента с 1 активным агентством определён верно",
                        ClientsLogins.LOGIN_FREE_ARCHIVED,
                        UsersStatusarch.Yes,
                        ClientsAllowCreateScampBySubclient.Yes,
                        new Object[][]{
                                {
                                        ClientsLogins.AGENCY_SH2,
                                        AgencyClientRelationsClientArchived.No,
                                        AgencyClientRelationsBind.Yes
                                },
                        },
                        YesNoEnum.YES
                },

                {
                        "статус архивации для свободного субклиента с 1 активным агентством определён верно",
                        ClientsLogins.LOGIN_FREE_ARCHIVED_NOT,
                        UsersStatusarch.No,
                        ClientsAllowCreateScampBySubclient.Yes,
                        new Object[][]{
                                {
                                        ClientsLogins.AGENCY_SH2,
                                        AgencyClientRelationsClientArchived.Yes,
                                        AgencyClientRelationsBind.Yes
                                }
                        },
                        YesNoEnum.NO
                },
                {
                        "статус архивации для активного агентства",
                        ClientsLogins.LOGIN_AGENCY,
                        UsersStatusarch.No,
                        null,
                        new Object[][]{},
                        YesNoEnum.NO
                },
                {
                        "статус архивации для архивного агентства",
                        ClientsLogins.AGENCY_ARCHIVED,
                        UsersStatusarch.Yes,
                        null,
                        new Object[][]{},
                        YesNoEnum.YES
                },
        });
    }

    private static Long longIdForLogin(String login) {
        return Long.valueOf(User.get(login).getClientID());
    }

    @Before
    public void init() {
        final int INDEX_LOGIN = 0;
        final int INDEX_ARCHIVED = 1;
        final int INDEX_BIND = 2;

        final long clientId = longIdForLogin(clientLogin);
        final int shard = api.userSteps.clientFakeSteps().getUserShard(clientLogin);
        final DirectJooqDbSteps directJooqDbSteps = api.userSteps.getDirectJooqDbSteps().useShard(shard);
        final ClientsSteps jooqClientSteps = directJooqDbSteps.clientsSteps();
        final UsersSteps jooqUsersSteps = directJooqDbSteps.usersSteps();
        final AgencyClientRelationsSteps jooqAgencyClientRelationsSteps =
                directJooqDbSteps.agencyClientRelationsSteps();

        if (usersStatusarch != null) {
            jooqUsersSteps.updateUsers(jooqUsersSteps.getUser(clientLogin).setStatusarch(usersStatusarch));
        }

        if (clientsAllowCreateScamp != null) {
            jooqClientSteps.setFree(clientId, clientsAllowCreateScamp);
        }

        for (Object[] agencyData : agenciesData) {
            final Long agencyId = longIdForLogin((String) agencyData[INDEX_LOGIN]);

            jooqAgencyClientRelationsSteps.update(
                    new AgencyClientRelationsRecord()
                            .setAgencyClientId(agencyId)
                            .setClientClientId(clientId)
                            .setBind((AgencyClientRelationsBind) agencyData[INDEX_BIND])
                            .setClientArchived((AgencyClientRelationsClientArchived) agencyData[INDEX_ARCHIVED])
            );
        }

    }

    @Test
    public void archiveStatusTest() {
        GetResponse getResponse = api.as(clientLogin)
                .userSteps.clientsStepsV5().clientsGet(
                        new GetRequestMap().withFieldNames(ClientFieldEnum.ARCHIVED));

        assertThat(comment, getResponse.getClients().get(0).getArchived(), equalTo(isArchived));
    }

    @Test
    public void archiveStatusTestBySuperUser() {
        GetResponse getResponse = api.as(ClientsLogins.SUPER_LOGIN)
                .userSteps.clientsStepsV5().clientsGet(
                        new GetRequestMap().withFieldNames(ClientFieldEnum.ARCHIVED),
                        clientLogin);

        assertThat(comment, getResponse.getClients().get(0).getArchived(), equalTo(isArchived));
    }
}
