/*

 */
package com.braintree.payment.validators.impl;


import com.braintree.exceptions.BraintreeResourceErrorMessage;
import com.braintree.payment.validators.BraintreePaymentMethodValidator;
import org.apache.commons.lang.StringUtils;

import java.util.Calendar;


public class DefaultBraintreeEditPaymentMethodValidator implements BraintreePaymentMethodValidator {

    public static final int BRAINTREE_CARDHOLDER_MAX_LENGTHS = 175;
    public static final int YEAR_LENGTH = 4;
    public static final int CVV_LENGTH_ALL = 3;
    public static final int CVV_LENGTH_AMERICAN_EXPRESS = 4;
    public static final String TEXT_ACCOUNT_PROFILE_PAYMENT_CART_EDIT_PAYMENT_METHOD_INVALID_EXPIRATION_DATE
            = "text.account.profile.paymentCart.editPaymentMethod.invalid.expirationDate";

    @Override
    public BraintreeResourceErrorMessage validate(final String cardholder, final String expirationDate, final String cvv) {
        if (StringUtils.isNotBlank(cardholder) && cardholder.length() > BRAINTREE_CARDHOLDER_MAX_LENGTHS) {
            return new BraintreeResourceErrorMessage(
                "text.account.profile.paymentCart.editPaymentMethod.invalid.cardholderTooLong");
        }

        if (StringUtils.isNotBlank(cvv) && (cvv.length() < CVV_LENGTH_ALL
            || cvv.length() > CVV_LENGTH_AMERICAN_EXPRESS)) {
            return new BraintreeResourceErrorMessage("text.account.profile.paymentCart.editPaymentMethod.invalid.cvv");
        }
        return validateExpirationDate(expirationDate);
    }

    private BraintreeResourceErrorMessage validateExpirationDate(String expirationDate) {
        if (StringUtils.isNotBlank(expirationDate)) {
            final String[] split = expirationDate.split("/");
            if (split.length == 2) {
                final String startMonth = split[0];
                final String startYear = split[1];
                return checkExpirationDate(startMonth, startYear);
            } else {
                return new BraintreeResourceErrorMessage(
                    TEXT_ACCOUNT_PROFILE_PAYMENT_CART_EDIT_PAYMENT_METHOD_INVALID_EXPIRATION_DATE);
            }
        } else {
            return new BraintreeResourceErrorMessage(
                "text.account.profile.paymentCart.editPaymentMethod.required.expirationDate");
        }
    }

    private BraintreeResourceErrorMessage checkExpirationDate(String startMonth, String startYear) {
        try {
            final Calendar entered = Calendar.getInstance();
            entered.set(Calendar.DAY_OF_MONTH, 0);
            entered.set(Calendar.MONTH, Integer.parseInt(startMonth) - 1);
            entered.set(Calendar.YEAR, Integer.parseInt(startYear));

            final Calendar current = Calendar.getInstance();
            if (startYear.length() == YEAR_LENGTH) {
                if (current.after(entered)) {
                    return new BraintreeResourceErrorMessage(
                        "text.account.profile.paymentCart.editPaymentMethod.error.expirationDate");
                }
            } else {
                return new BraintreeResourceErrorMessage(
                    TEXT_ACCOUNT_PROFILE_PAYMENT_CART_EDIT_PAYMENT_METHOD_INVALID_EXPIRATION_DATE);
            }
        } catch (NumberFormatException e) {
            return new BraintreeResourceErrorMessage(
                TEXT_ACCOUNT_PROFILE_PAYMENT_CART_EDIT_PAYMENT_METHOD_INVALID_EXPIRATION_DATE);
        }
        return new BraintreeResourceErrorMessage(StringUtils.EMPTY);
    }
}
