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

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.utils.money.Currency;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.apiclient.errors.AxisError;
import ru.yandex.autotests.directapi.apiclient.errors.AxisErrorDetails;
import ru.yandex.autotests.directapi.apiclient.methods.Method;
import ru.yandex.autotests.directapi.clients.ClientFeatures;
import ru.yandex.autotests.directapi.clients.ClientLogins;
import ru.yandex.autotests.directapi.common.api45.ClientInfo;
import ru.yandex.autotests.directapi.common.api45.CreateNewSubclientResponse;
import ru.yandex.autotests.directapi.model.campaigns.Status;
import ru.yandex.autotests.directapi.model.clients.ClientInfoMap;
import ru.yandex.autotests.directapi.model.common.Value;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.irt.testutils.allure.LogSteps;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.allure.annotations.Title;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import java.util.Arrays;

import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.hamcrest.Matchers.equalTo;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;
import static ru.yandex.autotests.irt.testutils.beandiffer.BeanDifferMatcher.beanEquivalent;

/**
 * Created by semkagtn on 11/28/14.
 */
@Aqua.Test
@Features(ClientFeatures.UPDATE_CLIENT_INFO)
@Description("Проверка обновления поля " + ClientInfoMap.DISPLAY_STORE_RATING)
public class UpdateClientInfoDisplayStoreRatingTest {

    private static final String AGENCY_LOGIN = ClientLogins.AGENCY_YE_DEFAULT;

    protected LogSteps log = LogSteps.getLogger(this.getClass());

    @ClassRule
    public static ApiSteps api = new ApiSteps().version(104).as(AGENCY_LOGIN);

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

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

    private String subClientLogin;

    @Before
    @Step("Подготовка данных для теста")
    public void createSubClient() {
        CreateNewSubclientResponse createNewSubclientResponse =
                api.userSteps.clientSteps().createNewAgencySubClient("agencySubClient", AGENCY_LOGIN, Currency.RUB);
        subClientLogin = createNewSubclientResponse.getLogin();
    }

    @Test
    @Title("Значение " + ClientInfoMap.DISPLAY_STORE_RATING + " по умолчанию равно " + Value.YES)
    @ru.yandex.qatools.allure.annotations.TestCaseId("5847")
    public void defaultDisplayStoreRatingValueIsYes() {
        ClientInfo clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assertThat("значение равно " + Value.YES, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.YES).getBean()));
    }

    @Test
    @Title("Установить значение " + ClientInfoMap.DISPLAY_STORE_RATING + " в " + Value.NO)
    @ru.yandex.qatools.allure.annotations.TestCaseId("5849")
    public void setNoDisplayStoreRatingValue() {
        api.userSteps.clientSteps().updateClientInfo(new ClientInfoMap(api.type())
                .defaultClientInfo()
                .withLogin(subClientLogin)
                .withDisplayStoreRating(Value.YES));
        ClientInfo clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assumeThat("значение равно " + Value.YES, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.YES).getBean()));

        api.userSteps.clientSteps().updateClientInfo(new ClientInfoMap(api.type())
                .defaultClientInfo()
                .withLogin(subClientLogin)
                .withDisplayStoreRating(Value.NO));
        clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assertThat("значение равно " + Value.NO, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.NO).getBean()));
    }

    @Test
    @Title("Установить значение " + ClientInfoMap.DISPLAY_STORE_RATING + " в " + Value.YES)
    @ru.yandex.qatools.allure.annotations.TestCaseId("5850")
    public void setYesDisplayStoreRatingValue() {
        api.userSteps.clientSteps().updateClientInfo(new ClientInfoMap(api.type())
                .defaultClientInfo()
                .withLogin(subClientLogin)
                .withDisplayStoreRating(Value.NO));
        ClientInfo clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assumeThat("значение равно " + Value.NO, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.NO).getBean()));

        api.userSteps.clientSteps().updateClientInfo(new ClientInfoMap(api.type())
                .defaultClientInfo()
                .withLogin(subClientLogin)
                .withDisplayStoreRating(Value.YES));
        clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assertThat("значение равно " + Value.YES, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.YES).getBean()));
    }

    @Test
    @Title("Установить невалидное значение поля " + ClientInfoMap.DISPLAY_STORE_RATING)
    @ru.yandex.qatools.allure.annotations.TestCaseId("5848")
    public void invalidFieldValue() {
        api.userSteps.shouldGetErrorOn(
                Method.UPDATE_CLIENT_INFO,
                Arrays.asList(new ClientInfoMap(api.type())
                        .defaultClientInfo()
                        .withLogin(subClientLogin)
                        .withDisplayStoreRating("incorrectValue").getBean()),
                new AxisError(25, AxisErrorDetails.INVALID_FIELD, capitalize(ClientInfoMap.DISPLAY_STORE_RATING)));
    }

    //@Test DIRECT-58301
    public void changeDisplayStoreRatingValueAndCheckStatusBsSynced() {
        api.userSteps.clientSteps().updateClientInfo(new ClientInfoMap(api.type())
                .defaultClientInfo()
                .withLogin(subClientLogin)
                .withDisplayStoreRating(Value.YES));
        ClientInfo clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assumeThat("значение равно " + Value.YES, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.YES).getBean()));
        Long textCid = api.userSteps.campaignStepsV5().addDefaultTextCampaign(subClientLogin);
        Long mobileAppCid = api.userSteps.campaignStepsV5().addDefaultMobileAppCampaign(subClientLogin);
        Long dynamicTextCid = api.userSteps.campaignStepsV5().addDefaultDynamicTextCampaign(subClientLogin);
        api.userSteps.campaignFakeSteps().setBSSynced(textCid, true);
        api.userSteps.campaignFakeSteps().setBSSynced(mobileAppCid, true);
        api.userSteps.campaignFakeSteps().setBSSynced(dynamicTextCid, true);
        api.userSteps.clientSteps().updateClientInfo(new ClientInfoMap(api.type())
                .defaultClientInfo()
                .withLogin(subClientLogin)
                .withDisplayStoreRating(Value.NO));
        clientInfo = api.userSteps.clientSteps().getClientInfo(subClientLogin);
        assumeThat("значение равно " + Value.NO, clientInfo, beanEquivalent(new ClientInfoMap(api.type())
                .withDisplayStoreRating(Value.NO).getBean()));
        assertThat("у текстовой кампании сбросился StatusBsSynced",
                api.userSteps.campaignFakeSteps().fakeGetCampaignParams(textCid).getStatusBsSynced(), equalTo(Status.NO));
        assertThat("у кампании РМП сбросился StatusBsSynced",
                api.userSteps.campaignFakeSteps().fakeGetCampaignParams(mobileAppCid).getStatusBsSynced(), equalTo(Status.NO));
        assertThat("у динамической текстовой кампании сбросился StatusBsSynced",
                api.userSteps.campaignFakeSteps().fakeGetCampaignParams(dynamicTextCid).getStatusBsSynced(), equalTo(Status.NO));
    }
}
