package com.agilex.vamf.missionhealth.domain;

import java.util.Date;

import com.agilex.vamf.utils.DateHelper;
import com.agilex.vamf.utils.NullSafeStringComparer;

/**
 * This class is used to represent a person's date of birth.  Date is stored internally as a string with its format to make
 * the more common toString() operation more preformant.
 */
public class DOBDate {
    private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory.getLog(DOBDate.class);
    private static final String DEFAULT_FORMAT = "MMM dd, yyyy";

    private final String format;
	private final String value;
    private final boolean isValid;

    /**
     *
     * @param dob   Null dob values are turned into empty Strings.  Expects date to be in DEFAULT_FORMAT format.
     */
	public DOBDate(Date dob) {
		this.format = DEFAULT_FORMAT;

		if (dob != null)
		    this.value = convertDateToString(dob);
        else {
            value = "";
            logger.warn("DOB was passed in as null.  Setting DOB date value to Empty String.");
        }

        isValid = value != "";
	}

    private String convertDateToString(Date dob) {
        try{
            return DateHelper.format(dob, this.format);
        } catch (Exception e) {
            logger.warn("Unable to format date for DOB using the default " + this.format + " format.  Setting DOB date value to Empty String.");
            return "";
        }
    }

    /**
     *
     * @param format    Null formats are changed to the DEFAULT_FORMAT
     * @param value     Null values are turned into empty Strings
     */
	public DOBDate(String format, String value) {
        if (format == null)
            this.format = DEFAULT_FORMAT;
        else
		    this.format = format;

        if (value == null)
            this.value = "";
        else
		    this.value = value;

        isValid = this.value != "" && getDate() != null;
    }

    /**
     * @return Date or Null if date is not valid for the specified format
     */
    public Date getDate() {
		try {
			return DateHelper.parse(this.value, this.format);
		} catch (Exception e) {
            logger.warn("Unable to parse date for DOB using " + this.format + " format.  Returning Null date.");
            return null;
		}
	}

    /**
     * @return  true if date not Null and is parsable by format specified at construction
     */
    public boolean isValid() {
        return isValid;
    }

    @Override
	public String toString() {
		return value;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		} else if (obj instanceof DOBDate) {
			DOBDate that = (DOBDate) obj;

            return (NullSafeStringComparer.areEqual(this.format, that.format) &&
                    NullSafeStringComparer.areEqual(this.value, that.value));
			}
		else {
			return false;
		}
	}
	
	@Override
	public int hashCode() {
		return value.hashCode() ^ format.hashCode();
	}
}
