package ru.yandex.autotests.directapi.finance.accountmanagement.transfer;

/**
 * Author pavryabov
 * Date 26.05.14
 */

import java.math.RoundingMode;

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.utils.money.Currency;
import ru.yandex.autotests.direct.utils.money.Money;
import ru.yandex.autotests.direct.utils.money.MoneyCurrency;
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.common.api45.Account;
import ru.yandex.autotests.directapi.common.api45.CreateNewSubclientResponse;
import ru.yandex.autotests.directapi.finance.FinanceFeatures;
import ru.yandex.autotests.directapi.model.Logins;
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.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.Matchers.equalTo;

@Aqua.Test
@Features(FinanceFeatures.ACCOUNT_MANAGEMENT_TRANSFER)
public class TransferOperationLimitTest {
    private LogSteps log = LogSteps.getLogger(this.getClass());

    private static final String AGENCY_LOGIN = Logins.AGENCY_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);

    private static int fromAccountID;
    private static int toAccountID;
    private static int accountIDElse;

    static final int operationNumberLimit = 3;
    static Money startSum = Money.valueOf(60000f, Currency.RUB);
    static float sum = MoneyCurrency.get(Currency.RUB).getMinTransferAmount().floatValue();

    @BeforeClass
    public static void createAccounts() {
        api.userSteps.clientFakeSteps().enableAgencyWallet(AGENCY_LOGIN);
        api.userSteps.clientFakeSteps().enableToCreateSubClients(AGENCY_LOGIN);
        CreateNewSubclientResponse createNewSubclientResponse =
                api.userSteps.clientSteps().createNewAgencySubClient("subClient", AGENCY_LOGIN, Currency.RUB);
        long fromCampaignID = api.userSteps.addActiveCampaign(
                createNewSubclientResponse.getLogin(), startSum.floatValue(), Currency.RUB);
        startSum = startSum.subtractVAT().setScale(2, RoundingMode.HALF_UP);
        fromAccountID = api.userSteps.financeSteps().enableAndGetSharedAccount(createNewSubclientResponse.getLogin());
        Account accountFrom = api.userSteps.financeSteps().getAccount(fromAccountID);
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.financeSteps().accountAmountIs(accountFrom), equalTo(startSum.floatValue()));
        createNewSubclientResponse =
                api.userSteps.clientSteps().createNewAgencySubClient("subClient", AGENCY_LOGIN, Currency.RUB);
        long toCampaignID1 = api.userSteps.addModeratedCampaign(createNewSubclientResponse.getLogin());
        toAccountID = api.userSteps.financeSteps().enableAndGetSharedAccount(createNewSubclientResponse.getLogin());
        Account accountTo = api.userSteps.financeSteps().getAccount(toAccountID);
        createNewSubclientResponse =
                api.userSteps.clientSteps().createNewAgencySubClient("subClient", AGENCY_LOGIN, Currency.RUB);
        long toCampaignID2 = api.userSteps.addActiveCampaign(
                createNewSubclientResponse.getLogin(), 2000f, Currency.RUB);

        accountIDElse = api.userSteps.financeSteps().enableAndGetSharedAccount(createNewSubclientResponse.getLogin());
        for (int i = 1; i <= operationNumberLimit; i++) {
            api.userSteps.financeSteps().transfer(fromAccountID, toAccountID, sum, Currency.RUB.toString());
            startSum = startSum.subtract(sum);
            ConditionFactories.NOTIFY_ORDER2.until(
                    api.userSteps.financeSteps().accountAmountIs(accountFrom), equalTo(startSum.floatValue()));
            ConditionFactories.NOTIFY_ORDER2.until(
                    api.userSteps.financeSteps().accountAmountIs(accountTo), equalTo(sum * i));
        }
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6119")
    public void transferFromAccountMoreThanLimit() {
        api.userSteps.financeSteps().shouldGetMultipleErrorOnTransfer(
                fromAccountID, accountIDElse, sum, Currency.RUB.toString(),
                new AxisError(56, AxisErrorDetails.REQUEST_LIMIT_EXCEEDED,
                        "AccountManagement Transfer", operationNumberLimit, operationNumberLimit, 1));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6120")
    public void transferToAccountMoreThanLimit() {
        api.userSteps.financeSteps().shouldGetMultipleErrorOnTransfer(
                accountIDElse, toAccountID, sum, Currency.RUB.toString(),
                new AxisError(56, AxisErrorDetails.REQUEST_LIMIT_EXCEEDED,
                        "AccountManagement Transfer", operationNumberLimit, operationNumberLimit, 1));
    }
}
