package ru.yandex.autotests.direct.api.campaigns.add.dynamictextcampaign;

import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;

import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.api.campaigns.CampaignsFeatures;
import ru.yandex.autotests.direct.api.campaigns.CampaignsLogins;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.campaigns.CampaignAddItemMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.DynamicTextCampaignAddItemMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.DynamicTextCampaignStrategyAddMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.PriorityGoalsArrayMap;
import ru.yandex.autotests.directapi.model.api5.campaigns.PriorityGoalsItemMap;
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.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.nullValue;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

@Aqua.Test
@Features(CampaignsFeatures.ADD)
@Description("Проверка создания кампании с PriorityGoals")
@Issue("https://st.yandex-team.ru/DIRECT-98633")
public class PriorityGoalsDBValuesTest {

    private static final String CLIENT = CampaignsLogins.CLIENT;
    private static final Integer COUNTER_ID = 32265784;
    private static final Long GOAL_ID = 13088934L;
    // цель CampaignsLogins.UPDATE_CLIENT, недоступная CLIENT
    private static final Integer ALIEN_COUNTER_ID = 34981090;
    private static final Long ALIEN_GOAL_ID = 17108070L;

    @ClassRule
    public static ApiSteps api = new ApiSteps().version(5).as(CLIENT);

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

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

    @BeforeClass
    public static void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(CLIENT);
    }

    @Test
    public void addWithoutPriorityGoals() {
        Long cid = api.userSteps.campaignSteps().addCampaign(new CampaignAddItemMap()
                .defaultCampaignAddItem()
                .withDynamicTextCampaign(new DynamicTextCampaignAddItemMap()
                        .withBiddingStrategy(new DynamicTextCampaignStrategyAddMap()
                                .defaultDynamicTextCampaignStrategy()))
        );

        assertThat("meaningful_goals пустой",
                api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT).campaignsSteps()
                        .getCampOptionsById(cid).getMeaningfulGoals(),
                nullValue());
    }

    @Test
    public void addWithEngagedSessionsPriorityGoal() {
        Long cid = api.userSteps.campaignSteps().addCampaign(new CampaignAddItemMap()
                .defaultCampaignAddItem()
                .withDynamicTextCampaign(new DynamicTextCampaignAddItemMap()
                        .withBiddingStrategy(new DynamicTextCampaignStrategyAddMap()
                                .defaultDynamicTextCampaignStrategy())
                        .withPriorityGoals(new PriorityGoalsArrayMap()
                                .withItems(new PriorityGoalsItemMap()
                                        .withEngagedSessionGoalId()
                                        .withValue(1_000_000L))))
        );

        assertThat("meaningful_goals содержит правильный json",
                api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT).campaignsSteps()
                        .getCampOptionsById(cid).getMeaningfulGoals(),
                anyOf(
                        equalTo("[{\"goal_id\": " + PriorityGoalsItemMap.ENGAGED_SESSION_GOAL_ID + ", \"value\": " +
                                "\"1\"}]"),
                        equalTo("[{\"value\": \"1\", \"goal_id\": " + PriorityGoalsItemMap.ENGAGED_SESSION_GOAL_ID +
                                "}]"),
                        // через интерфейс фронт автоматом форматирует до двух знаков после запятой
                        // поэтому это норм, что и api5 будет делать так же (менять 1, на 1.00)
                        equalTo("[{\"goal_id\": " + PriorityGoalsItemMap.ENGAGED_SESSION_GOAL_ID + ", \"value\": \"1" +
                                ".00\"}]"),
                        equalTo("[{\"value\": \"1.00\", \"goal_id\": " + PriorityGoalsItemMap.ENGAGED_SESSION_GOAL_ID + "}]")
                ));
    }

    @Test
    public void addWithCounterGoal() {
        addAndCheckCampaignWithCounterGoal(COUNTER_ID, GOAL_ID);
    }

    @Test
    public void addWithInaccessibleCounterGoal() {
        DirectJooqDbSteps dbSteps = api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT);
        Long clientId = Long.parseLong(User.get(CLIENT).getClientID());
        dbSteps.featuresSteps().setClientFeature(clientId, "direct_unavailable_goals_allowed", true);

        addAndCheckCampaignWithCounterGoal(ALIEN_COUNTER_ID, ALIEN_GOAL_ID);
    }

    private void addAndCheckCampaignWithCounterGoal(int counterId, long goalId) {
        Long cid = api.userSteps.campaignSteps().addCampaign(new CampaignAddItemMap()
                .defaultCampaignAddItem()
                .withDynamicTextCampaign(new DynamicTextCampaignAddItemMap()
                        .withBiddingStrategy(new DynamicTextCampaignStrategyAddMap()
                                .defaultDynamicTextCampaignStrategy())
                        .withCounterIds(counterId)
                        .withPriorityGoals(new PriorityGoalsArrayMap()
                                .withItems(new PriorityGoalsItemMap()
                                        .withGoalId(goalId)
                                        .withValue(1_000_000L))))
        );

        assertThat("meaningful_goals содержит правильный json",
                api.userSteps.getDirectJooqDbSteps().useShardForLogin(CLIENT).campaignsSteps()
                        .getCampOptionsById(cid).getMeaningfulGoals(),
                anyOf(
                        equalTo("[{\"goal_id\": " + goalId + ", \"value\": \"1\"}]"),
                        equalTo("[{\"value\": \"1\", \"goal_id\": " + goalId + "}]"),
                        // через интерфейс фронт автоматом форматирует до двух знаков после запятой
                        // поэтому это норм, что и api5 будет делать так же (менять 1, на 1.00)
                        equalTo("[{\"goal_id\": " + goalId + ", \"value\": \"1.00\"}]"),
                        equalTo("[{\"value\": \"1.00\", \"goal_id\": " + goalId + "}]")
                ));
    }
}
