package ru.yandex.autotests.direct.api.campaigns.suspend;

import java.sql.Timestamp;
import java.util.List;

import org.joda.time.DateTime;
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.models.jooq.ppc.tables.records.CampOptionsRecord;
import ru.yandex.autotests.direct.utils.date.DBTimeConverter;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.fake.CampaignFakeInfo;
import ru.yandex.autotests.directapi.darkside.model.Status;
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.Tag;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Title;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * Created by chicos on 14.08.15.
 */
@Aqua.Test
@Features(CampaignsFeatures.SUSPEND)
@Description("Проверка времени изменения и статусов в БД при остановке кампании")
@Tag(TagDictionary.TRUNK)
public class SuspendCampaignsDBStatusTest {
    private static LogSteps log = LogSteps.getLogger(SuspendCampaignsDBStatusTest.class);
    private static final String client = CampaignsLogins.SINGLE_CLIENT_SUSPEND;
    private static final DateTime lastChange = DateTime.now().minusMonths(1);
    private static final String lastChangeStr = DBTimeConverter.jodaTimeToDb(lastChange);
    private static final Timestamp lastChangeTs = DBTimeConverter.jodaToSql(lastChange);

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

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

    private static CampaignFakeInfo campaignInfo;
    private static Long campaignId;
    private static int shard;

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

    @BeforeClass
    public static void initTest() {
        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(client);
        shard = api.userSteps.clientFakeSteps().getUserShard(client);
        campaignId = api.userSteps.campaignSteps().addDefaultTextCampaign();
        Long groupID = api.userSteps.adGroupsSteps().addDefaultGroup(campaignId);
        Long adID = api.userSteps.adsSteps().addDefaultTextAd(groupID);

        log.info("Промодерируем фейково");
        api.userSteps.campaignFakeSteps().makeCampaignModerated(campaignId);
        api.userSteps.groupFakeSteps().makeGroupFullyModerated(groupID);
        api.userSteps.bannersFakeSteps().makeBannersModerated(adID);

        log.info("Выставим статусы синхронизации с БК фейково");
        api.userSteps.campaignFakeSteps().setBSSynced(campaignId, true);
        api.userSteps.groupFakeSteps().setGroupFakeStatusBsSynced(groupID, Status.YES);
        api.userSteps.bannersFakeSteps().setStatusBsSynced(adID, Status.YES);

        log.info("Сдвинем время последнего изменения на несколько дней");
        api.userSteps.campaignFakeSteps().setLastChange(campaignId, lastChangeStr);
        CampOptionsRecord options = api.userSteps.getDirectJooqDbSteps().useShard(shard).campaignsSteps()
                .getCampOptionsById(campaignId);
        options.setStoptime(lastChangeTs);

        log.info("Остановим кампанию");
        List<Long> ids = api.userSteps.campaignSteps().campaignsSuspend(campaignId);
        assumeThat("получили идентификатор остановленной кампании", ids, hasSize(1));
        campaignInfo = api.userSteps.campaignFakeSteps().fakeGetCampaignParams(campaignId);
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("614")
    public void statusBsSyncedTest() {
        assertThat("статус синхронизации с БК после остановки кампании", campaignInfo.getStatusBsSynced(),
                equalTo(Value.NO));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("615")
    public void statusShowTest() {
        assertThat("поле StatusShow после остановки кампании", campaignInfo.getStatusShow(), equalTo(Value.NO));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("617")
    public void stopTimeTest() {
        final CampOptionsRecord campOptions = api.userSteps.getDirectJooqDbSteps().useShard(shard).campaignsSteps()
                .getCampOptionsById(campaignId);
        assertThat("время остановки кампании", lastChangeTs, lessThan(campOptions.getStoptime()));
    }

    @Title("Bug: DIRECT-40604")
    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("616")
    public void lastChangeTest() {
        final DateTime newLastChange = DBTimeConverter
                .dbTimeToJoda(api.userSteps.campaignFakeSteps().fakeGetCampaignParams(campaignId).getLastChange());

        assertThat("время последнего изменения кампании после остановки кампании изменилось",
                lastChange, lessThan(newLastChange));
    }
}
