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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.yandex.webmaster3.core.semantic.review_business.ModelUtils;

import java.util.Date;

import static com.google.common.base.Strings.isNullOrEmpty;

/**
 * This class contains base info about review moderation. Childs should add RejReasons for specific review
 * types to contain all info about review moderation
 * <p/>
 * @author Dima Schitinin <dimas@yandex-team.ru>
 * @author Evgeny Zhoga <ezhoga@yandex-team.ru>
 */
public abstract class ReviewModeration {

    private static final Logger log = LoggerFactory.getLogger(ReviewModeration.class);

    /**
     * Moderation status of review
     */
    public enum Status {
        /**
         * New review. Indicates no moderation actions.
         */
        NEW,
        /**
         * Indicates review under moderation.
         * For example, sent to QAS or under administrator investigation.
         */
        IN_PROGRESS,
        /**
         * Review satisfies to all conditions and can be shown for external users.
         */
        ACCEPTED,
        /**
         * Review doesn't satisfy to conditions and must not be shown for external users.
         */
        DECLINED;

        public static Status safeValueOf(final String name) {
            if (isNullOrEmpty(name))
                return null;
            try {
                return valueOf(name);
            } catch (IllegalArgumentException e) {
                log.error("Unknown status: " + name);
                return null;
            }
        }
    }

    /**
     * Handler of review and creator of moderation status.
     */
    public enum Handler {
        /**
         * External moderator (from QAS)
         */
        MODERATOR,
        /**
         * Somebody from review administrator interface
         */
        ADMINISTRATOR,
        /**
         * Status has been encountered automatically
         */
        AUTO;

        public static Handler safeValueOf(final String name) {
            if (isNullOrEmpty(name))
                return null;
            try {
                return valueOf(name);
            } catch (IllegalArgumentException e) {
                log.error("Unknown handler: " + name);
                return null;
            }
        }
    }

    public abstract Status getStatus();

    public abstract String getCustomRejectionText();

    public abstract Handler getHandler();

    public abstract Date getTime();

    /**
     * Internalized rejection text
     */
    public abstract String getRejectionText();

    /**
     * Some note can be leaved from administrator.
     * To be visible only from admistrator interface.
     */
    public abstract String getNote();

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

        final ReviewModeration that = (ReviewModeration) o;

        return hashCode() == that.hashCode()
                && ModelUtils.equals(getStatus(), that.getStatus())
                && ModelUtils.equals(getCustomRejectionText(), that.getCustomRejectionText())
                && ModelUtils.equals(getHandler(), that.getHandler())
                && ModelUtils.equals(getTime(), that.getTime())
                && ModelUtils.equals(getNote(), that.getNote())
                && ModelUtils.equals(getRejectionText(), that.getRejectionText())
                ;
    }

    @Override
    public int hashCode() {
        return ModelUtils.hashCode(
                getStatus()
                ,getCustomRejectionText()
                ,getHandler()
                ,getTime()
                ,getNote()
                ,getRejectionText()
        );
    }

}
