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

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

/**
 * Represents information about user environment
 * at the time of review creation.
 * It should be used for calculate trust level of user.
 * UserIdentity is available only for UGC reviews,
 * e.g. reviews that have been created at the service.
 * <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/>
 * User: willzyx
 * Date: 3/30/12 - 6:56 PM
 */
public abstract class UserIdentity {
    /**
     * Cookie YandexUid.
     * For details see http://wiki.yandex-team.ru/Cookies
     *
     * @return cookie yandexuid. Null signals for off-design state.
     */
    public abstract String getYandexUid();

    /**
     * Flash-cookie.
     * For details see:
     * * http://wiki.yandex-team.ru/Cookies
     * * http://wiki.yandex-team.ru/JandeksPoisk/IzmerenijaStatistika/FleshKuka
     *
     * @return flash-cookie.
     *         Null typically signals for out-design state and rarely that user hasn't flash.
     */
    public abstract String getFUid01();

    /**
     * @return User-Agent of user's browser.
     *         Null typically signals for out-design state and rarely that user cleans HTTP-headers
     *         or something else abnormal.
     */
    public abstract String getUserAgent();

    /**
     * @return IP-address of the user.
     *         Null signals for out-design state.
     */
    public abstract String getIp();

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

        final UserIdentity that = (UserIdentity) o;

        return hashCode() == that.hashCode()
                && ModelUtils.equals(getYandexUid(), that.getYandexUid())
                && ModelUtils.equals(getFUid01(), that.getFUid01())
                && ModelUtils.equals(getUserAgent(), that.getUserAgent())
                && ModelUtils.equals(getIp(), that.getIp());
    }

    @Override
    public int hashCode() {
        return ModelUtils.hashCode(
                getYandexUid()
                ,getFUid01()
                ,getUserAgent()
                ,getIp()
        );
    }

    /**
     * Construct string representation of UserIdentity.
     * All not-null and not-empty members will be presented there.
     */
    @Override
    public String toString() {
        try {
            return UserIdentityJsonConversions.toJson(this).toString(1);
        } catch (JSONException e) {
            throw new AssertionError("Not expected to be thrown");
        }
    }
}

