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

import com.yandex.direct.api.v5.agencyclients.AddResponse;
import org.junit.Before;
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.db.steps.DirectJooqDbSteps;
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.darkside.datacontainers.jsonrpc.fake.CampaignFakeInfo;
import ru.yandex.autotests.directapi.darkside.model.Status;
import ru.yandex.autotests.directapi.finance.FinanceFeatures;
import ru.yandex.autotests.directapi.finance.FinanceLogins;
import ru.yandex.autotests.directapi.matchers.finance.AccountMatcher;
import ru.yandex.autotests.directapi.model.User;
import ru.yandex.autotests.directapi.model.api5.agencyclients.AddRequestMap;
import ru.yandex.autotests.directapi.model.finances.PayCampElementMap;
import ru.yandex.autotests.directapi.model.finances.sharedaccount.EnableSharedAccountRequestMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.autotests.directapi.rules.Trashman;
import ru.yandex.autotests.directapi.steps.ConditionFactories;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assumeThat;

/**
 * User: mariabye
 * Date: 05.11.13
 */
@Aqua.Test
@Features(FinanceFeatures.ENABLE_SHARED_ACCOUNT)
public class EnableSharedAccountCampaignStatusTest {

    public static String agencyLogin = FinanceLogins.AGENCY_ENABLE_SHARED_ACCOUNT;
    Money minInvoiceSum = MoneyCurrency.get(Currency.RUB).getMinInvoiceAmount().addVAT();
    private static final Money MIN_INVOICE_SUM_NO_VAT = MoneyCurrency.get(Currency.RUB).getMinInvoiceAmount();

    @ClassRule
    public static ApiSteps api = new ApiSteps().version(104).as(FinanceLogins.AGENCY_ENABLE_SHARED_ACCOUNT);

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

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

    @BeforeClass
    public static void sharedAccountFlagOn() {
        DirectJooqDbSteps jooqDbSteps = api.userSteps.getDirectJooqDbSteps().useShardForLogin(agencyLogin);
        Long agencyId = jooqDbSteps.usersSteps().getUser(agencyLogin).getClientid();
        jooqDbSteps.agencyOptionsSteps().allowCreateClientsWithoutWallet(agencyId);
        api.userSteps.clientFakeSteps().enableToCreateSubClients(agencyLogin);

    }

    private String clientLogin;
    @Before
    public void createClientWithoutSharedAccount()
    {
        AddResponse clientAddResponse = api.userSteps.agencyClientsStepsV5()
                .agencyClientsAdd(
                        new AddRequestMap()
                                .withDefault(AddRequestMap.generateLogin("sh"))
                                .withoutSharedAccount(),
                        agencyLogin
                );
        clientLogin = clientAddResponse.getLogin();
    }

    //https://jira.yandex-team.ru/browse/DIRECT-26237
    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6275")
    public void newSubclientNoCampaigns() {
        api.userSteps.financeSteps().shouldGetErrorsOnEnableSharedAccount(
                new EnableSharedAccountRequestMap(api.type()).withLogins(clientLogin),
                new AxisError(520, AxisErrorDetails.TO_ENABLE_SHARED_ACCOUNT_AT_LEAST_ONE_CAMPAIGN_REQUIRED));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6276")
    public void newSubclientDraftCampaign() {
        api.userSteps.addDraftCampaign(clientLogin);
        int accountID = api.userSteps.financeSteps().enableAndGetSharedAccount(clientLogin);
        Account account = api.userSteps.financeSteps().getAccount(accountID);
        assertThat(account, allOf(AccountMatcher.hasAmount(equalTo(0f))));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6277")
    public void newSubclientArchivedCampaign() {
        long campaignID = api.userSteps.addDraftCampaign(clientLogin);

        api.userSteps.campaignSteps().campaignsSuspend(clientLogin, campaignID);
        api.userSteps.campaignSteps().campaignsArchive(clientLogin, campaignID);
        int accountID = api.userSteps.financeSteps().enableAndGetSharedAccount(clientLogin);
        Account account = api.userSteps.financeSteps().getAccount(accountID);
        assertThat(account, allOf(AccountMatcher.hasAmount(equalTo(0f))));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6278")
    public void newSubclientDeletedCampaign() {
        long campaignID = api.userSteps.addDraftCampaign(clientLogin);
        api.userSteps.campaignSteps().campaignsDelete(clientLogin, campaignID);
        api.userSteps.financeSteps().shouldGetErrorsOnEnableSharedAccount(
                new EnableSharedAccountRequestMap(api.type()).withLogins(clientLogin),
                new AxisError(520, AxisErrorDetails.CAMPAIGN_CREATION_REQUIRED_FOR_ACCOUNT_ENABLING));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6279")
    public void newSubclientCampaignsWithSums() {
        api.userSteps.addDraftCampaign(clientLogin);
        long activeCid1 = api.userSteps.addActiveCampaign(clientLogin, minInvoiceSum.floatValue(), Currency.RUB);
        ConditionFactories.NOTIFY_ORDER2
                .until(api.userSteps.campaignSteps().campaignFundsChanged(clientLogin, activeCid1));
        long activeCid2 = api.userSteps.addActiveCampaign(clientLogin, minInvoiceSum.floatValue(), Currency.RUB);
        ConditionFactories.NOTIFY_ORDER2
                .until(api.userSteps.campaignSteps().campaignFundsChanged(clientLogin, activeCid2));
        int accountID = api.userSteps.financeSteps().enableAndGetSharedAccount(clientLogin);
        ConditionFactories.NOTIFY_ORDER2.until(
                api.userSteps.financeSteps().accountAmountIs(api.userSteps.financeSteps().getAccount(accountID)),
                equalTo(MIN_INVOICE_SUM_NO_VAT.multiply(2).floatValue()));
    }

    @Test
    @ru.yandex.qatools.allure.annotations.TestCaseId("6280")
    public void newSubclientCampaignsWaitingMoney() {
        long campaignID1 = api.userSteps.addModeratedCampaign(clientLogin);

        String requestID = api.userSteps.financeSteps().getRequestID(
                new PayCampElementMap(api.type())
                        .withCampaignID(campaignID1)
                        .withCurrency(Currency.RUB)
                        .withSum(minInvoiceSum.floatValue())
        );
        int invoiceID = api.userSteps.balanceSteps().operator(User.get(agencyLogin))
                .createInvoice(requestID);

        int accountID = api.userSteps.financeSteps().enableAndGetSharedAccount(clientLogin);
        Account account = api.userSteps.financeSteps().getAccount(accountID);
        assertThat(account, AccountMatcher.hasAmount(equalTo(0f)));

        api.userSteps.balanceSteps().turnOnInvoice(invoiceID);

        ConditionFactories.NOTIFY_ORDER2.until(api.userSteps.financeSteps().accountAmountChanged(account));

        account = api.userSteps.financeSteps().getAccount(accountID);
        assertThat(account, AccountMatcher.hasAmount(equalTo(MIN_INVOICE_SUM_NO_VAT.floatValue())));
    }

    @Test
    public void checkCampaignStatusBsSyncedAfterEnableWallet() {
        long campaignId = api.userSteps.addDraftCampaign(clientLogin);
        api.userSteps.campaignFakeSteps().makeCampaignFullyModerated(campaignId);
        api.userSteps.campaignFakeSteps().setBSSynced(campaignId, true);
        CampaignFakeInfo campaignFakeInfo = api.userSteps.campaignFakeSteps().fakeGetCampaignParams(campaignId);
        assumeThat("кампания синхронизирована с БК", campaignFakeInfo.getStatusBsSynced(), equalTo(Status.YES));
        api.userSteps.financeSteps().enableAndGetSharedAccount(clientLogin);
        campaignFakeInfo = api.userSteps.campaignFakeSteps().fakeGetCampaignParams(campaignId);
        assumeThat("кампания не синхронизирована с БК", campaignFakeInfo.getStatusBsSynced(), equalTo(Status.NO));
    }
}
