package ru.yandex.autotests.direct.api.adgroups.add;

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

import javax.xml.ws.handler.MessageContext;

import com.sun.xml.ws.developer.WSBindingProvider;
import com.yandex.direct.api.v5.adgroups.AdGroupsPort;
import com.yandex.direct.api.v5.adgroups.AddRequest;
import com.yandex.direct.api.v5.adgroups.ApiException;
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.api.adgroups.AdGroupsFeatures;
import ru.yandex.autotests.direct.api.adgroups.AdGroupsLogins;
import ru.yandex.autotests.directapi.ApiStories;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.enums.CampaignType;
import ru.yandex.autotests.directapi.model.api5.adgroups.AdGroupAddItemMap;
import ru.yandex.autotests.directapi.model.api5.adgroups.AddRequestMap;
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.allure.annotations.Stories;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.equalTo;
import static ru.yandex.autotests.directapi.rules.ApiSteps.USE_OPERATOR_UNITS_AUTO;
import static ru.yandex.autotests.directapi.rules.ApiSteps.USE_OPERATOR_UNITS_FALSE;
import static ru.yandex.autotests.directapi.rules.ApiSteps.USE_OPERATOR_UNITS_TRUE;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by onotole on 8/2/16.
 * https://st.yandex-team.ru/TESTIRT-9945
 */
@Aqua.Test
@Features(AdGroupsFeatures.ADD)
@Stories(ApiStories.UNITS)
@Issue("https://st.yandex-team.ru/DIRECT-53941")
@Description("при списании баллов в ответе возвращается заголовок с логином того, с кого списали баллы")
@RunWith(Parameterized.class)
public class UnitsUsedLoginInHeadersTest {
    private static final String DEFAULT_CLIENT = AdGroupsLogins.CLIENT;
    private static final String AGENCY = AdGroupsLogins.AGENCY;
    private static final String SUBCLIENT = AdGroupsLogins.SUBCLIENT;
    private static final String CLIENT_MAIN_REPRESENTATIVE = AdGroupsLogins.CLIENT;
    private static final String CLIENT_REPRESENTATIVE = AdGroupsLogins.CLIENT_REP;

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

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

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

    @Parameterized.Parameter(0)
    public String comment;

    @Parameterized.Parameter(1)
    public static String client;

    @Parameterized.Parameter(2)
    public static String operator;

    @Parameterized.Parameter(3)
    public static String expectedClientInResponse;

    @Parameterized.Parameter(4)
    public static String useOperatorUnits;

    @Parameterized.Parameter(5)
    public static boolean subclientHasInsufficientPoints;

    @Parameterized.Parameters(name = "{0}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {"Самостоятельный клиент", DEFAULT_CLIENT, DEFAULT_CLIENT, DEFAULT_CLIENT, USE_OPERATOR_UNITS_FALSE, false},
                {"Агенство и сабклиент, баллы агенства", SUBCLIENT, AGENCY, AGENCY, USE_OPERATOR_UNITS_TRUE, false},
                {"Агенство и сабклиент, баллы клиента", SUBCLIENT, AGENCY, SUBCLIENT, USE_OPERATOR_UNITS_FALSE, false},
                {"Для главного представителя возвращается он же", CLIENT_MAIN_REPRESENTATIVE, CLIENT_MAIN_REPRESENTATIVE,
                        CLIENT_MAIN_REPRESENTATIVE, USE_OPERATOR_UNITS_FALSE, false},
                {"Для обычного представителя возвращается он же", CLIENT_REPRESENTATIVE,
                        CLIENT_REPRESENTATIVE, CLIENT_REPRESENTATIVE, USE_OPERATOR_UNITS_FALSE, false},
                {"В режиме Use-Operator-Units:auto возвращается агентство, если клиенту не хватает баллов",
                        SUBCLIENT, AGENCY, AGENCY, USE_OPERATOR_UNITS_AUTO, true},
                {"В режиме Use-Operator-Units:auto возвращается клиент, если ему хватает баллов", SUBCLIENT,
                        AGENCY, SUBCLIENT, USE_OPERATOR_UNITS_AUTO, false}
        });
    }

    @Before
    public void clearSpentUnits() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(operator);
    }

    @Test
    public void checkUnitsUsedLoginAgencyInHeaders() throws ApiException {
        Long campaignId = api.as(operator).userSteps.campaignSteps().addDefaultCampaign(client, CampaignType.TEXT);
        api.as(operator).useOperatorUnits(useOperatorUnits);

        if (subclientHasInsufficientPoints) {
            api.userSteps.clientFakeSteps()
                    .fakeWithdrawClientUnits(client, api.userSteps.clientFakeSteps().fakeClientUnitsBalance(client));
        }

        AdGroupsPort adGroupsPort = api.userSteps.soapClientV5().adGroupsService(client);
        adGroupsPort.add((AddRequest) new AddRequestMap().withAdGroups(
                new AdGroupAddItemMap().defaultAdGroupAddItem(campaignId)).getBean());
        WSBindingProvider bp = (WSBindingProvider) adGroupsPort;
        TreeMap responseHeaders = (TreeMap) bp.getResponseContext().get(MessageContext.HTTP_RESPONSE_HEADERS);

        String unitsUsedLoginHeader = "Units-Used-Login";
        assumeThat("Header Units-Used-Login содержится в ответе", responseHeaders.containsKey(unitsUsedLoginHeader),
                equalTo(true));
        assertThat("Header Units-Used-Login содержит имя правильного юзера",
                ((List) responseHeaders.get(unitsUsedLoginHeader)).get(0).toString(), equalTo(expectedClientInResponse));
    }
}
