package ru.yandex.autotests.direct.api.creatives;

import com.yandex.direct.api.v5.creatives.CpcVideoCreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.CpmVideoCreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.CreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.CreativeGetItem;
import com.yandex.direct.api.v5.creatives.CreativeTypeEnum;
import com.yandex.direct.api.v5.creatives.GetResponse;
import com.yandex.direct.api.v5.creatives.VideoExtensionCreativeFieldEnum;
import com.yandex.direct.api.v5.general.YesNoEnum;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.PerfCreativesRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.creatives.CpcVideoCreativeGetItemMap;
import ru.yandex.autotests.directapi.model.api5.creatives.CpmVideoCreativeGetItemMap;
import ru.yandex.autotests.directapi.model.api5.creatives.CreativeGetItemMap;
import ru.yandex.autotests.directapi.model.api5.creatives.CreativesSelectionCriteriaMap;
import ru.yandex.autotests.directapi.model.api5.creatives.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.creatives.VideoExtensionCreativeGetItemMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.qatools.Tag;
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 com.yandex.direct.api.v5.creatives.CreativeTypeEnum.CPC_VIDEO_CREATIVE;
import static com.yandex.direct.api.v5.creatives.CreativeTypeEnum.CPM_VIDEO_CREATIVE;
import static com.yandex.direct.api.v5.creatives.CreativeTypeEnum.HTML_5_CREATIVE;
import static com.yandex.direct.api.v5.creatives.CreativeTypeEnum.IMAGE_CREATIVE;
import static com.yandex.direct.api.v5.creatives.CreativeTypeEnum.VIDEO_EXTENSION_CREATIVE;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertThat;
import static ru.yandex.autotests.directapi.matchers.beans.version5.BeanDifferMatcherV5.beanDifferV5;
import static ru.yandex.autotests.directapi.model.Logins.CLIENT_IN_2_SHARD;

@Aqua.Test
@Features(CreativesFeatures.GET)
@Description("Проверка соответствия возвращаемых полей, при запросе всех полей")
@Issue("https://st.yandex-team.ru/DIRECT-84024")
@Tag(TagDictionary.TRUNK)
public class FullRequestTest {

    private static String client = CLIENT_IN_2_SHARD;// CreativesLogins.CLIENT1;

    @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);

    private static PerfCreativesRecord imageCreativeRecord;
    private static PerfCreativesRecord html5CreativeRecord;
    private static PerfCreativesRecord videoExtensionCreativeRecord;
    private static PerfCreativesRecord cpcVideoCreativeRecord;
    private static PerfCreativesRecord cpmVideoCreativeRecord;

    @BeforeClass
    public static void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        long clientId = Long.parseLong(User.get(client).getClientID());

        DirectJooqDbSteps jooqDbSteps =
                api.userSteps.getDarkSideSteps().getDirectJooqDbSteps().useShardForLogin(client);

        long imageCreativeId = jooqDbSteps.perfCreativesSteps().saveDefaultCanvasCreativesForClient(clientId);
        imageCreativeRecord = jooqDbSteps.perfCreativesSteps().getPerfCreatives(imageCreativeId);

        //long html5CreativeId = jooqDbSteps.perfCreativesSteps().saveDefaultHtml5CreativesForClient(clientId);
        //html5CreativeRecord = jooqDbSteps.perfCreativesSteps().getPerfCreatives(html5CreativeId);

        long videoExtensionCreativeId = jooqDbSteps.perfCreativesSteps().saveDefaultVideoCreative(clientId, 5L);
        videoExtensionCreativeRecord = jooqDbSteps.perfCreativesSteps().getPerfCreatives(videoExtensionCreativeId);

        long cpcVideoCreativeId = jooqDbSteps.perfCreativesSteps().saveDefaultVideoCreative(clientId, 51L);
        cpcVideoCreativeRecord = jooqDbSteps.perfCreativesSteps().getPerfCreatives(cpcVideoCreativeId);

        long cpmVideoCreativeId = jooqDbSteps.perfCreativesSteps().saveDefaultVideoCreative(clientId, 7L);
        cpmVideoCreativeRecord = jooqDbSteps.perfCreativesSteps().getPerfCreatives(cpmVideoCreativeId);
    }

    @Test
    public void getImageCreativeWithAllFields() {
        GetResponse getResponse = getResponseWithAllFiels(imageCreativeRecord.getCreativeId());

        assertThat("вернулось объявление с правильным набором полей",
                getResponse.getCreatives(),
                beanDifferV5(singletonList((CreativeGetItem)
                        baseCreativeGetItemFromRecord(imageCreativeRecord, IMAGE_CREATIVE)
                                .getBean())));
    }

    @Test
    @Ignore
    public void getHtml5CreativeWithAllFields() {
        GetResponse getResponse = getResponseWithAllFiels(html5CreativeRecord.getCreativeId());

        assertThat("вернулось объявление с правильным набором полей",
                getResponse.getCreatives(),
                beanDifferV5(singletonList((CreativeGetItem)
                        baseCreativeGetItemFromRecord(html5CreativeRecord, HTML_5_CREATIVE)
                                .getBean())));
    }

    @Test
    public void getVideoExtensionCreativeWithAllFields() {
        GetResponse getResponse = getResponseWithAllFiels(videoExtensionCreativeRecord.getCreativeId());

        VideoExtensionCreativeGetItemMap videoExtensionCreativeGetItemMap = new VideoExtensionCreativeGetItemMap();
        if (videoExtensionCreativeRecord.getDuration() != null) {
            videoExtensionCreativeGetItemMap.withDuration(videoExtensionCreativeRecord.getDuration().intValue());
        }

        assertThat("вернулось объявление с правильным набором полей",
                getResponse.getCreatives(),
                beanDifferV5(singletonList((CreativeGetItem)
                        baseCreativeGetItemFromRecord(videoExtensionCreativeRecord, VIDEO_EXTENSION_CREATIVE)
                                .withVideoExtensionCreative(videoExtensionCreativeGetItemMap)
                                .getBean())));
    }

    @Test
    public void getCpcVideoCreativeWithAllFields() {
        GetResponse getResponse = getResponseWithAllFiels(cpcVideoCreativeRecord.getCreativeId());

        CpcVideoCreativeGetItemMap cpcVideoCreativeGetItemMap = new CpcVideoCreativeGetItemMap();
        if (cpcVideoCreativeRecord.getDuration() != null) {
            cpcVideoCreativeGetItemMap.withDuration(cpcVideoCreativeRecord.getDuration().intValue());
        }

        assertThat("вернулось объявление с правильным набором полей",
                getResponse.getCreatives(),
                beanDifferV5(singletonList((CreativeGetItem)
                        baseCreativeGetItemFromRecord(cpcVideoCreativeRecord, CPC_VIDEO_CREATIVE)
                                .withCpcVideoCreative(cpcVideoCreativeGetItemMap)
                                .getBean())));
    }

    @Test
    public void getCpmVideoCreativeWithAllFields() {
        GetResponse getResponse = getResponseWithAllFiels(cpmVideoCreativeRecord.getCreativeId());

        CpmVideoCreativeGetItemMap cpmVideoCreativeGetItemMap = new CpmVideoCreativeGetItemMap();
        cpmVideoCreativeGetItemMap.withDuration(cpmVideoCreativeRecord.getDuration().intValue());

        assertThat("вернулось объявление с правильным набором полей",
                getResponse.getCreatives(),
                beanDifferV5(singletonList((CreativeGetItem)
                        baseCreativeGetItemFromRecord(cpmVideoCreativeRecord, CPM_VIDEO_CREATIVE)
                                .withCpmVideoCreative(cpmVideoCreativeGetItemMap)
                                .getBean())));
    }

    @Test
    public void getTwoCreativesByIdsInSelectionCriteria() {
        long creativeId1 = videoExtensionCreativeRecord.getCreativeId();
        long creativeId2 = cpcVideoCreativeRecord.getCreativeId();

        GetResponse getResponse = api.userSteps.creativeSteps().creativesGet(new GetRequestMap()
                .withSelectionCriteria(new CreativesSelectionCriteriaMap().withIds(creativeId1, creativeId2))
                .withFieldNames(CreativeFieldEnum.ID));

        CreativeGetItem expected1 = new CreativeGetItem();
        expected1.setId(creativeId1);

        CreativeGetItem expected2 = new CreativeGetItem();
        expected2.setId(creativeId2);

        assertThat("вернулось 2 объекта по запрошенным идентификаторам",
                getResponse.getCreatives(),
                beanDifferV5(asList(expected1, expected2)));
    }

    @Test
    public void getTwoCreativesByTypesInSelectionCriteria() {
        long creativeId1 = imageCreativeRecord.getCreativeId();
        long creativeId2 = videoExtensionCreativeRecord.getCreativeId();

        GetResponse getResponse = api.userSteps.creativeSteps().creativesGet(new GetRequestMap()
                .withSelectionCriteria(new CreativesSelectionCriteriaMap().withIds(creativeId1, creativeId2))
                .withFieldNames(CreativeFieldEnum.values()));

        CreativeGetItem expected1 = (CreativeGetItem)
                baseCreativeGetItemFromRecord(imageCreativeRecord, IMAGE_CREATIVE).getBean();

        CreativeGetItem expected2 = (CreativeGetItem)
                baseCreativeGetItemFromRecord(videoExtensionCreativeRecord, VIDEO_EXTENSION_CREATIVE).getBean();

        assertThat("вернулось 2 объекта по запрошенным типам",
                getResponse.getCreatives(),
                beanDifferV5(asList(expected1, expected2)));
    }

    private GetResponse getResponseWithAllFiels(Long creativeId) {
        return api.userSteps.creativeSteps().creativesGet(new GetRequestMap()
                .withSelectionCriteria(new CreativesSelectionCriteriaMap().withIds(creativeId))
                .withFieldNames(CreativeFieldEnum.values())
                .withVideoExtensionFieldNames(VideoExtensionCreativeFieldEnum.values())
                .withCpcVideoCreativeFieldNames(CpcVideoCreativeFieldEnum.values())
                .withCpmVideoCreativeFieldNames(CpmVideoCreativeFieldEnum.values())
        );
    }

    private CreativeGetItemMap baseCreativeGetItemFromRecord(PerfCreativesRecord record, CreativeTypeEnum type) {
        return new CreativeGetItemMap()
                .withId(record.getCreativeId())
                .withType(type)
                .withName(record.getName())
                .withPreviewUrl(record.getPreviewUrl())
                .withThumbnailUrl(record.getLivePreviewUrl())
                .withWidth(record.getWidth() != null ? record.getWidth().intValue() : null)
                .withHeight(record.getHeight() != null ? record.getHeight().intValue() : null)
                .witAssociated(YesNoEnum.NO)
                .withIsAdaptive(YesNoEnum.NO);
    }
}
