package ru.yandex.webmaster3.core.semantic.review_business.biz.model;

import org.json.JSONException;
import ru.yandex.webmaster3.core.semantic.review_business.ModelUtils;
import ru.yandex.webmaster3.core.semantic.review_business.biz.model.impl.json.AddressJsonConversions;

/**
 * Represents address (one of available addresses)
 * of the business under review.
 * <p/>
 * Getters of this class are used to count hashCode, so to keep contract (see first point in {@link Object#hashCode()})
 * they should return objects which have same hashCode value during application run time
 * In general - implementation should be immutable and return references which are also immutable
 * <p/>
 *
 * @author Dima Schitinin <dimas@yandex-team.ru>
 */
public abstract class Address {
    public abstract String getCountryName();

    public abstract String getRegion();

    public abstract String getLocality();

    public abstract String getStreetAddress();

    public abstract String getExtendedAddress();

    public abstract String getPostalCode();

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (!(o instanceof Address)) return false;

        final Address address = (Address) o;

        return hashCode() == o.hashCode()
                && ModelUtils.equals(getCountryName(), address.getCountryName())
                && ModelUtils.equals(getExtendedAddress(), address.getExtendedAddress())
                && ModelUtils.equals(getLocality(), address.getLocality())
                && ModelUtils.equals(getPostalCode(), address.getPostalCode())
                && ModelUtils.equals(getRegion(), address.getRegion())
                && ModelUtils.equals(getStreetAddress(), address.getStreetAddress());
    }

    @Override
    public int hashCode() {
        return ModelUtils.hashCode(
                getCountryName()
                , getExtendedAddress()
                , getLocality()
                , getPostalCode()
                , getRegion()
                , getStreetAddress()
        );
    }

    @Override
    public String toString() {
        try {
            return AddressJsonConversions.toJson(this).toString(1);
        } catch (JSONException e) {
            throw new AssertionError("Not expected to be thrown");
        }
    }
}

