package ru.yandex.autotests.directapi.finance.paycampaigns;

import java.util.Arrays;
import java.util.Collection;

import com.yandex.direct.api.v5.campaigns.CampaignGetItem;
import org.junit.Before;
import org.junit.BeforeClass;
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.utils.money.Currency;
import ru.yandex.autotests.direct.utils.money.Money;
import ru.yandex.autotests.direct.utils.money.MoneyCurrency;
import ru.yandex.autotests.direct.utils.tags.TagDictionary;
import ru.yandex.autotests.directapi.ApiFeatures;
import ru.yandex.autotests.directapi.apiclient.config.ProtocolType;
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.model.Logins;
import ru.yandex.autotests.directapi.model.finances.PayCampElementMap;
import ru.yandex.autotests.directapi.model.finances.PayCampaignsInfoMap;
import ru.yandex.autotests.directapi.model.finances.PayMethod;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.steps.ConditionFactories;
import ru.yandex.autotests.irt.testutils.allure.LogSteps;
import ru.yandex.qatools.Tag;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Title;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

/**
 * Author pavryabov
 * Date 16.04.14
 */
@Aqua.Test
@Features(ApiFeatures.BUG)
@Tag(TagDictionary.TRUNK)
@Tag(TagDictionary.BUG)
@RunWith(Parameterized.class)
public class PayCampaignsYMTestFailed {
    private LogSteps log = LogSteps.getLogger(this.getClass());

    private static final String AGENCY_LOGIN = Logins.AGENCY_YE_DEFAULT;
    private static final String CLIENT_LOGIN = Logins.CLIENT_FREE_YE_DEFAULT;
    private static final Money ALLOWED_PAYMENT = Money.valueOf(15000f, Currency.RUB);

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

    @Parameterized.Parameter(0)
    public ProtocolType protocol;

    @Parameterized.Parameters(name = "ProtocolType = {0}")
    public static Collection roleValues() {
        return Arrays.asList((Object[][]) new Object[][]{
                {ProtocolType.SOAP},
                {ProtocolType.JSON}
        });
    }

    private static Money sum = MoneyCurrency.get(null).getMinInvoiceAmount();
    protected static long activeCampaignID1;
    protected static long activeCampaignID2;
    protected static long draftCampaignID;
    protected static long moderatedCampaignID;

    @BeforeClass
    public static void initTest() {
        activeCampaignID1 = api.userSteps.addActiveCampaign(CLIENT_LOGIN, 1);
        activeCampaignID2 = api.userSteps.addActiveCampaign(CLIENT_LOGIN, 1);
        draftCampaignID = api.userSteps.addDraftCampaign(CLIENT_LOGIN);
        moderatedCampaignID = api.userSteps.addModeratedCampaign(CLIENT_LOGIN);
    }

    @Before
    public void setProtocol() {
        api.protocol(protocol);
    }

    @Test
    @Title("Bug DIRECT-30929")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6457")
    public void testPayDraftAndActiveCampaign() {
        //DIRECT-30929
        log.info("Попытка оплаты черновика вместе с активной кампанией");
        api.userSteps.financeSteps().shouldGetErrorOnPayCampaignsYM(
                new AxisError(354, AxisErrorDetails.CAMPAIGN_NOT_MODERATED, draftCampaignID),
                new PayCampaignsInfoMap(api.type())
                        .withPayMethod(PayMethod.YM)
                        .withPayments(new PayCampElementMap(api.type())
                                        .withCampaignID(draftCampaignID)
                                        .withSum(sum.floatValue()),
                                new PayCampElementMap(api.type())
                                        .withCampaignID(activeCampaignID2)
                                        .withSum(sum.floatValue()))
        );
    }

    @Test
    @Title("Bug DIRECT-32175")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6458")
    public void testPayCampaignMoreThenAllowedPayment() {
        log.info("Оплата кампании на сумму превыщающую лимит для физ. лица");
        api.userSteps.financeSteps().shouldGetErrorOnPayCampaignsYM(
                new AxisError(365, AxisErrorDetails.LIMIT_EXCEEDED),
                new PayCampaignsInfoMap(api.type())
                        .withPayMethod(PayMethod.YM)
                        .withPayments(new PayCampElementMap(api.type())
                                .withCampaignID(activeCampaignID1)
                                .withSum(ALLOWED_PAYMENT.convert(null).getNext().floatValue()))
        );
    }

    @Test
    @Title("Bug DIRECT-32175")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6459")
    public void testPayCampaignsOneSumMoreThenAllowedPayment() {
        log.info("Оплата кампании на сумму превыщающую лимит для физ. лица");
        api.userSteps.financeSteps().shouldGetErrorOnPayCampaignsYM(
                new AxisError(365, AxisErrorDetails.LIMIT_EXCEEDED),
                new PayCampaignsInfoMap(api.type())
                        .withPayMethod(PayMethod.YM)
                        .withPayments(new PayCampElementMap(api.type())
                                        .withCampaignID(activeCampaignID1)
                                        .withSum(sum.floatValue()),
                                new PayCampElementMap(api.type())
                                        .withCampaignID(activeCampaignID2)
                                        .withSum(ALLOWED_PAYMENT.convert(null).getNext().floatValue()))
        );
    }

    @Test
    @Title("TESTIRT-10089")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6449")
    public void testPayModeratedAndActiveCampaign() {
        log.info("Оплата модерированной и активной кампаний");
        CampaignGetItem campaignModerated =
                api.userSteps.campaignSteps().getCampaign(CLIENT_LOGIN, moderatedCampaignID);
        CampaignGetItem campaignActive = api.userSteps.campaignSteps().getCampaign(CLIENT_LOGIN, activeCampaignID1);
        int response = api.userSteps.financeSteps().payCampaignsYM(
                new PayCampElementMap(api.type())
                        .withCampaignID(moderatedCampaignID)
                        .withSum(sum.floatValue()),
                new PayCampElementMap(api.type())
                        .withCampaignID(activeCampaignID1)
                        .withSum(sum.floatValue()));
        assertThat("Метод PayCampaigns вернул неуспешный код завершения операции", response, equalTo(1));
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(campaignModerated, sum));
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(campaignActive, sum));
    }

    @Test
    @Title("TESTIRT-10089")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6450")
    public void testPayActiveCampaign() {
        log.info("Оплата активной кампании");
        CampaignGetItem campaign = api.userSteps.campaignSteps().getCampaign(CLIENT_LOGIN, activeCampaignID1);
        int response = api.userSteps.financeSteps().payCampaignsYM(
                new PayCampElementMap(api.type())
                        .withCampaignID(activeCampaignID1)
                        .withSum(sum.floatValue()));
        assertThat("Метод PayCampaigns вернул неуспешный код завершения операции", response, equalTo(1));
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(campaign, sum));
    }

    @Test
    @Title("TESTIRT-10089")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6451")
    public void testPayTwoActiveCampaigns() {
        log.info("Оплата двух активных кампаний");
        CampaignGetItem campaignActive1 = api.userSteps.campaignSteps().getCampaign(CLIENT_LOGIN, activeCampaignID1);
        CampaignGetItem campaignActive2 = api.userSteps.campaignSteps().getCampaign(CLIENT_LOGIN, activeCampaignID2);
        int response = api.userSteps.financeSteps().payCampaignsYM(
                new PayCampElementMap(api.type())
                        .withCampaignID(activeCampaignID1)
                        .withSum(sum.floatValue()),
                new PayCampElementMap(api.type())
                        .withCampaignID(activeCampaignID2)
                        .withSum(sum.floatValue()));
        assertThat("Метод PayCampaigns вернул неуспешный код завершения операции", response, equalTo(1));
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(campaignActive1, sum));
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(campaignActive2, sum));
    }

    @Test
    @Title("TESTIRT-10089")
    @ru.yandex.qatools.allure.annotations.TestCaseId("6447")
    public void testPayModeratedCampaign() {
        log.info("Оплата модерированной кампании");
        CampaignGetItem campaign = api.userSteps.campaignSteps().getCampaign(CLIENT_LOGIN, moderatedCampaignID);
        int response = api.userSteps.financeSteps().payCampaignsYM(
                new PayCampElementMap(api.type())
                        .withCampaignID(moderatedCampaignID)
                        .withSum(sum.floatValue()));
        assertThat("Метод PayCampaigns вернул неуспешный код завершения операции", response, equalTo(1));
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(campaign, sum));
    }
}
