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

import java.util.List;

import com.yandex.direct.api.v5.campaigns.CampaignGetItem;
import com.yandex.direct.api.v5.general.CurrencyEnum;
import com.yandex.direct.api.v5.general.StatusEnum;
import org.junit.AfterClass;
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.httpclient.data.sandbox.APISandboxClientTypeEnum;
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.directapi.ApiFeatures;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.finances.PayCampElementMap;
import ru.yandex.autotests.directapi.model.finances.TransferMoneyInfoMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.sandbox.SandboxLogins;
import ru.yandex.autotests.directapi.steps.ConditionFactories;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.containsString;
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;

/**
 * Author pavryabov
 * Date 27.10.14
 * https://st.yandex-team.ru/TESTIRT-2839
 */
@Aqua.Test
@Features(ApiFeatures.SANDBOX)
public class CurrencyTest {

    @ClassRule
    public static ApiSteps api = new ApiSteps();

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

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

    private static final String client = SandboxLogins.SANDBOX_INIT_CLIENT7;
    Money minInvoiceAmount = MoneyCurrency.get(Currency.RUB).getMinInvoiceAmount().addVAT();
    private static Long campaignID;

    @BeforeClass
    public static void initSandbox() {
        api.as(client).userSteps.sandboxSteps()
                .enableSandboxByApi(client, APISandboxClientTypeEnum.CLIENT, true, Currency.RUB, false);
        List<CampaignGetItem> moderatedCampaigns = api.userSteps.campaignSteps().getAcceptedCampaigns(client);
        assumeThat("у клиента есть промодерированная кампания", moderatedCampaigns.size(), equalTo(1));
        campaignID = moderatedCampaigns.get(0).getId();
    }

    @Test
    public void createCampaignWithCurrency() {
        Long campaignIDWithCurrency = api.userSteps.campaignSteps().addDefaultTextCampaign(client);
        CampaignGetItem campaign = api.userSteps.campaignSteps().getCampaigns(campaignIDWithCurrency).get(0);
        assertThat("созданная кампания является валютной",
                campaign.getCurrency(), equalTo(CurrencyEnum.RUB));
    }


    @Test
    public void createInvoice() {
        PayCampElementMap payCampElementMap = new PayCampElementMap(api.type())
                .withCampaignID(campaignID.intValue())
                .withCurrency(Currency.RUB)
                .withSum(minInvoiceAmount.floatValue());
        String invoiceURL = api.userSteps.financeSteps().createInvoiceSandbox(payCampElementMap);
        assertThat("сформирован корректный URL выставленного счета", invoiceURL, containsString("request_id"));
    }


    @Test
    public void transferMoney() throws InterruptedException {
        Long campaignIdTo = api.userSteps.campaignSteps().addDefaultTextCampaign(client);
        Long adGroupId = api.userSteps.adGroupsSteps().addDefaultGroup(campaignIdTo);
        api.userSteps.keywordsSteps().addDefaultKeyword(adGroupId);
        Long adId = api.userSteps.adsSteps().addDefaultTextAd(adGroupId);
        api.userSteps.adsSteps().adsModerate(adId);
        ConditionFactories.SANDBOX_STATUS.until(
                api.userSteps.adsSteps().statusChanged(adId, StatusEnum.ACCEPTED));
        ConditionFactories.SANDBOX_STATUS.until(
                api.userSteps.campaignSteps().campaignStatusIs(client, campaignIdTo), equalTo(StatusEnum.ACCEPTED));
        CampaignGetItem campaignInfoFrom = api.userSteps.campaignSteps().getCampaigns(campaignID).get(0);
        CampaignGetItem campaignInfoTo = api.userSteps.campaignSteps().getCampaigns(campaignIdTo).get(0);
        TransferMoneyInfoMap transferMoneyInfoMap = new TransferMoneyInfoMap(api.type())
                .withFromCampaigns(new PayCampElementMap(api.type())
                        .withCampaignID(campaignID.intValue())
                        .withCurrency(Currency.RUB)
                        .withSum(minInvoiceAmount.floatValue()))
                .withToCampaigns(new PayCampElementMap(api.type())
                        .withCampaignID(campaignIdTo.intValue())
                        .withCurrency(Currency.RUB)
                        .withSum(minInvoiceAmount.floatValue()));
        api.userSteps.financeSteps().transferMoneySandbox(transferMoneyInfoMap);
        ConditionFactories.SANDBOX_STATUS.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(client,
                        campaignInfoFrom, -minInvoiceAmount.bidLong().longValue(), true));
        ConditionFactories.SANDBOX_STATUS.until(
                api.userSteps.campaignSteps().campaignFundsChangedOnFunds(client,
                        campaignInfoTo, minInvoiceAmount.bidLong().longValueForSum(), true));
    }

    @AfterClass
    public static void closeSandbox() {
        api.userSteps.sandboxSteps().closeSandbox(client);
    }
}
