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

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

import com.yandex.direct.api.v5.clients.ClientFieldEnum;
import com.yandex.direct.api.v5.clients.GetResponse;
import com.yandex.direct.api.v5.generalclients.ClientRestrictionEnum;
import com.yandex.direct.api.v5.generalclients.ClientRestrictionItem;
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.clients.ClientsFeatures;
import ru.yandex.autotests.directapi.clients.ClientsLogins;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.clients.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.generalclients.ClientRestrictionItemMap;
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.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.directapi.matchers.beandiffer2.BeanDifferMatcherV5.beanDifferV5;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

/**
 * Created by buhter on 10/02/16.
 * https://st.yandex-team.ru/TESTIRT-8440
 */
@Aqua.Test
@Features(ClientsFeatures.GET)
@Issue("https://st.yandex-team.ru/DIRECT-49746")
@Description("Проверки получения поля Limits")
@RunWith(Parameterized.class)
public class GetRestrictionsTest {
    //Настройки на весь Директ
    private static final int ADS_TOTAL_PER_ADGROUP = 50;
    private static final int STAT_REPORTS_TOTAL_IN_QUEUE = 5;
    private static final int FORECAST_REPORTS_TOTAL_IN_QUEUE = 5;
    private static final int WORDSTAT_REPORTS_TOTAL_IN_QUEUE = 5;

    private static final Long DEFAULT_CAMPAIGNS_TOTAL_PER_CLIENT = 3000L;
    private static final Long DEFAULT_CAMPAIGNS_UNARCHIVED_PER_CLIENT = 1000L;
    private static final Long DEFAULT_ADGROUPS_TOTAL_PER_CAMPAIGN = 1000L;
    private static final Long DEFAULT_KEYWORDS_TOTAL_PER_ADGROUP = 200L;
    private static final Long CUSTOM_CAMPAIGNS_TOTAL_PER_CLIENT = 4000L;
    private static final Long CUSTOM_CAMPAIGNS_UNARCHIVED_PER_CLIENT = 2000L;
    private static final Long CUSTOM_ADGROUPS_TOTAL_PER_CAMPAIGN = 2000L;
    private static final Long CUSTOM_KEYWORDS_TOTAL_PER_ADGROUP = 400L;
    private static final Long DEFAULT_API_POINTS = 160000L;
    private static final Long CUSTOM_API_POINTS = 400000L;
    private static final Long DEFAULT_AD_EXTENSIONS_TOTAL = 1000L;
    private static final Long DEFAULT_GENERAL_DOMAIN_BLACKLIST_SIZE = 1000L;
    private static final Long DEFAULT_VIDEO_DOMAIN_BLACKLIST_SIZE = 40L;

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

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

    @Parameterized.Parameter(0)
    public String login;

    @Parameterized.Parameter(1)
    public Long bannerCountLimit;

    @Parameterized.Parameter(2)
    public Long campaignCountLimit;

    @Parameterized.Parameter(3)
    public Long unarchivedCampaignCountLimit;

    @Parameterized.Parameter(4)
    public Long keywordsCountLimit;

    @Parameterized.Parameter(5)
    public Long apiUnits;

    @Parameterized.Parameter(6)
    public List<Object> expectedRestrictionItems;

    private static Object buildClientRestrictionItemMap(ClientRestrictionEnum element, int value) {
        return new ClientRestrictionItemMap().withElement(element).withValue(value).getBean();
    }

    @Parameterized.Parameters(name = "{0}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {ClientsLogins.LOGIN_LIMIT, 0L, 0L, 0L, 0L, 0L, Arrays.asList(
                        buildClientRestrictionItemMap(ClientRestrictionEnum.CAMPAIGNS_TOTAL_PER_CLIENT,
                                DEFAULT_CAMPAIGNS_TOTAL_PER_CLIENT.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.CAMPAIGNS_UNARCHIVED_PER_CLIENT,
                                DEFAULT_CAMPAIGNS_UNARCHIVED_PER_CLIENT.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.ADGROUPS_TOTAL_PER_CAMPAIGN,
                                DEFAULT_ADGROUPS_TOTAL_PER_CAMPAIGN.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.ADS_TOTAL_PER_ADGROUP,
                                ADS_TOTAL_PER_ADGROUP),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.KEYWORDS_TOTAL_PER_ADGROUP,
                                DEFAULT_KEYWORDS_TOTAL_PER_ADGROUP.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.STAT_REPORTS_TOTAL_IN_QUEUE,
                                STAT_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.FORECAST_REPORTS_TOTAL_IN_QUEUE,
                                FORECAST_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.WORDSTAT_REPORTS_TOTAL_IN_QUEUE,
                                WORDSTAT_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.API_POINTS, DEFAULT_API_POINTS.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.AD_EXTENSIONS_TOTAL,
                                DEFAULT_AD_EXTENSIONS_TOTAL.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.GENERAL_DOMAIN_BLACKLIST_SIZE,
                                DEFAULT_GENERAL_DOMAIN_BLACKLIST_SIZE.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.VIDEO_DOMAIN_BLACKLIST_SIZE,
                                DEFAULT_VIDEO_DOMAIN_BLACKLIST_SIZE.intValue())
                )},
                {ClientsLogins.LOGIN_LIMIT_1, DEFAULT_ADGROUPS_TOTAL_PER_CAMPAIGN, DEFAULT_CAMPAIGNS_TOTAL_PER_CLIENT
                        , DEFAULT_CAMPAIGNS_UNARCHIVED_PER_CLIENT, DEFAULT_KEYWORDS_TOTAL_PER_ADGROUP,
                        DEFAULT_API_POINTS
                        , Arrays.asList(
                        buildClientRestrictionItemMap(ClientRestrictionEnum.CAMPAIGNS_TOTAL_PER_CLIENT,
                                DEFAULT_CAMPAIGNS_TOTAL_PER_CLIENT.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.CAMPAIGNS_UNARCHIVED_PER_CLIENT,
                                DEFAULT_CAMPAIGNS_UNARCHIVED_PER_CLIENT.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.ADGROUPS_TOTAL_PER_CAMPAIGN,
                                DEFAULT_ADGROUPS_TOTAL_PER_CAMPAIGN.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.ADS_TOTAL_PER_ADGROUP,
                                ADS_TOTAL_PER_ADGROUP),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.KEYWORDS_TOTAL_PER_ADGROUP,
                                DEFAULT_KEYWORDS_TOTAL_PER_ADGROUP.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.STAT_REPORTS_TOTAL_IN_QUEUE,
                                STAT_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.FORECAST_REPORTS_TOTAL_IN_QUEUE,
                                FORECAST_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.WORDSTAT_REPORTS_TOTAL_IN_QUEUE,
                                WORDSTAT_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.API_POINTS, DEFAULT_API_POINTS.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.AD_EXTENSIONS_TOTAL,
                                DEFAULT_AD_EXTENSIONS_TOTAL.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.GENERAL_DOMAIN_BLACKLIST_SIZE,
                                DEFAULT_GENERAL_DOMAIN_BLACKLIST_SIZE.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.VIDEO_DOMAIN_BLACKLIST_SIZE,
                                DEFAULT_VIDEO_DOMAIN_BLACKLIST_SIZE.intValue())
                )},
                {ClientsLogins.LOGIN_LIMIT_2, CUSTOM_ADGROUPS_TOTAL_PER_CAMPAIGN, CUSTOM_CAMPAIGNS_TOTAL_PER_CLIENT
                        , CUSTOM_CAMPAIGNS_UNARCHIVED_PER_CLIENT, CUSTOM_KEYWORDS_TOTAL_PER_ADGROUP, CUSTOM_API_POINTS
                        , Arrays.asList(
                        buildClientRestrictionItemMap(ClientRestrictionEnum.CAMPAIGNS_TOTAL_PER_CLIENT,
                                CUSTOM_CAMPAIGNS_TOTAL_PER_CLIENT.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.CAMPAIGNS_UNARCHIVED_PER_CLIENT,
                                CUSTOM_CAMPAIGNS_UNARCHIVED_PER_CLIENT.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.ADGROUPS_TOTAL_PER_CAMPAIGN,
                                CUSTOM_ADGROUPS_TOTAL_PER_CAMPAIGN.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.ADS_TOTAL_PER_ADGROUP,
                                ADS_TOTAL_PER_ADGROUP),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.KEYWORDS_TOTAL_PER_ADGROUP,
                                CUSTOM_KEYWORDS_TOTAL_PER_ADGROUP.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.STAT_REPORTS_TOTAL_IN_QUEUE,
                                STAT_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.FORECAST_REPORTS_TOTAL_IN_QUEUE,
                                FORECAST_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.WORDSTAT_REPORTS_TOTAL_IN_QUEUE,
                                WORDSTAT_REPORTS_TOTAL_IN_QUEUE),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.API_POINTS, CUSTOM_API_POINTS.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.AD_EXTENSIONS_TOTAL,
                                DEFAULT_AD_EXTENSIONS_TOTAL.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.GENERAL_DOMAIN_BLACKLIST_SIZE,
                                DEFAULT_GENERAL_DOMAIN_BLACKLIST_SIZE.intValue()),
                        buildClientRestrictionItemMap(ClientRestrictionEnum.VIDEO_DOMAIN_BLACKLIST_SIZE,
                                DEFAULT_VIDEO_DOMAIN_BLACKLIST_SIZE.intValue())
                )},
        });
    }

    @Before
    public void clear() {
        api.as(login);
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(login);
        Long clientId = Long.valueOf(User.get(login).getClientID());
        Integer shard = api.userSteps.clientFakeSteps().getUserShard(clientId.intValue());
        api.userSteps.getDirectJooqDbSteps().useShard(shard).clientsApiOptionsSteps().setUnitsDaily(clientId, apiUnits);

        api.userSteps.getDirectJooqDbSteps().clientsLimitsSteps()
                .addOrUpdateClientLimitsKeywordCount(clientId, keywordsCountLimit);
        api.userSteps.clientFakeSteps().setBannerCountLimit(login, bannerCountLimit.intValue());
        api.userSteps.clientFakeSteps().setCampaignCountLimit(login, campaignCountLimit.intValue());
        api.userSteps.clientFakeSteps().setUnarchivedCampaignCountLimit(login, unarchivedCampaignCountLimit.intValue());
    }

    @Test
    public void getLimitsTest() {
        GetResponse getResponse = api.userSteps.clientsStepsV5().clientsGet(
                new GetRequestMap().withFieldNames(ClientFieldEnum.RESTRICTIONS));

        List<ClientRestrictionItem> actualRestrictionItems = getResponse.getClients().get(0).getRestrictions();
        actualRestrictionItems.sort(Comparator.comparing(ClientRestrictionItem::getElement));

        expectedRestrictionItems.sort(Comparator.comparing(e -> ((ClientRestrictionItem) e).getElement()));

        assertThat("полученные поля совпадают с ожидаемыми", actualRestrictionItems,
                beanDifferV5(expectedRestrictionItems));
    }
}
