package ru.yandex.autotests.direct.utils;

import java.math.RoundingMode;

import org.junit.Test;

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.money.MoneyFormat;

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

/**
 * @author Roman Kuhta (kuhtich@yandex-team.ru)
 */
public class MoneyTest {

    @Test
    public void convertYndFixedIntoRub() {
        Money chasInRubles = Money.valueOf(1.0, Currency.YND_FIXED);
        assertThat(chasInRubles.convert(Currency.RUB).setScale(RoundingMode.UP).floatValue(), equalTo(25.0f));
    }

    @Test
    public void convertFromRubIntoYndFixed() {
        Money chasInRubles = Money.valueOf(25.0, Currency.RUB);
        assertThat(chasInRubles.convert(Currency.YND_FIXED).setScale(RoundingMode.UP).floatValue(), equalTo(1.0f));
    }

    @Test
    public void enrollment() {
        double discount = 0.1;
        Money cashPaidInRubles = Money.valueOf(3000.0, Currency.RUB);
        Money cashOnCampaignInRubles = cashPaidInRubles.subtractVAT();
        Money cashInYndFixed = cashOnCampaignInRubles.convert(Currency.YND_FIXED);
        Float paidAmountInYndFixed = cashInYndFixed.withDiscount(discount).
                setScale(2, RoundingMode.HALF_UP).floatValue();
        assertThat(paidAmountInYndFixed, equalTo(111.11f));
    }

    @Test
    public void enrollmentInOneChain() {
        double discount = 0.1;
        Float paidAmountInYndFixed = Money.valueOf(3000.0, Currency.RUB).subtractVAT()
                .convert(Currency.YND_FIXED).withDiscount(discount).setScale(2, RoundingMode.HALF_UP).floatValue();
        assertThat(paidAmountInYndFixed, equalTo(111.11f));
    }

    @Test
    public void ukrainianCurrencyAbbreviationInEnglish() {
        assertThat(MoneyCurrency.get(Currency.UAH).getAbbreviation("en"), equalTo("UAH"));
    }

    @Test
    public void turkishCurrencyNameInEnglish() {
        assertThat(MoneyCurrency.get(Currency.TRY).getNamePluralI("en"), equalTo("Turkish Lira"));
    }

    @Test
    public void kztCurrencyFormatInEnglish() {
        assertThat(MoneyCurrency.get(Currency.KZT).getFormatPattern("en"), equalTo("#,##0.00"));
    }

    @Test
    public void usdCurrencyFormatInRussian() {
        assertThat(MoneyCurrency.get(Currency.USD).getNamePluralI("ru"), equalTo("Доллары США"));
    }

    @Test
    public void correctFloatValueSaved() {
        Float value = 123.4568793245354623f;
        assertThat(Money.valueOf(value).floatValue(), equalTo(value));
    }

    @Test
    public void correctDoubleValueSaved() {
        Double value = 1235476435764543.4568793245354623d;
        assertThat(Money.valueOf(value).doubleValue(), equalTo(value));
    }

    @Test
    public void toStringCurrencyRub() {
        assertThat(Money.valueOf(1L, Currency.RUB).toString(), equalTo("1 RUB"));
    }

    @Test
    public void toStringCurrencyNull() {
        assertThat(Money.valueOf(1L, (Currency) null).toString(), equalTo("1 YND_FIXED"));
    }

    @Test
    public void stringValuesTest() {
        Money money = Money.valueOf(1000000.00001);
        assertThat(money.stringValue(MoneyFormat.INTEGER), equalTo("1000000"));
        assertThat(money.stringValue(MoneyFormat.INTEGER_SEPARATED),
                equalTo("1" + (char) 0xa0 + "000" + (char) 0xa0 + "000"));
        assertThat(money.stringValue(MoneyFormat.INTEGER_SPACE_SEPARATED),
                equalTo("1" + (char) 0x20 + "000" + (char) 0x20 + "000"));
        assertThat(money.stringValue(MoneyFormat.ONE_DIGIT_COMMA), equalTo("1000000,0"));
        assertThat(money.stringValue(MoneyFormat.ONE_DIGIT_COMMA_SEPARATED),
                equalTo("1" + (char) 0xa0 + "000" + (char) 0xa0 + "000,0"));
        assertThat(money.stringValue(MoneyFormat.ONE_DIGIT_POINT), equalTo("1000000.0"));
        assertThat(money.stringValue(MoneyFormat.ONE_DIGIT_POINT_SEPARATED),
                equalTo("1" + (char) 0xa0 + "000" + (char) 0xa0 + "000.0"));
        assertThat(money.stringValue(MoneyFormat.TWO_DIGITS_COMMA_SEPARATED),
                equalTo("1" + (char) 0xa0 + "000" + (char) 0xa0 + "000,00"));
        assertThat(money.stringValue(MoneyFormat.TWO_DIGITS_COMMA), equalTo("1000000,00"));
        assertThat(money.stringValue(MoneyFormat.TWO_DIGITS_POINT_SEPARATED),
                equalTo("1" + (char) 0xa0 + "000" + (char) 0xa0 + "000.00"));
        assertThat(money.stringValue(MoneyFormat.TWO_DIGITS_POINT), equalTo("1000000.00"));
    }
}
