package com.atlassian.stash.internal.server;

import com.atlassian.bitbucket.validation.annotation.RequiredString;

import javax.annotation.Nonnull;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Note that this is not a Hibernate entity because it is used to initialize Hazelcast, and Hibernate depends on
 * Hazelcast for its caching.
 */
public class ApplicationProperty {

    static final int MAX_VALUE_SIZE = 2000;

    private final Key key;

    @RequiredString(size = MAX_VALUE_SIZE)
    private final String value;

    public ApplicationProperty(@Nonnull Key key, @Nonnull String value) {
        this.key = checkNotNull(key, "key");
        this.value = checkNotNull(value, "value");
    }

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

        ApplicationProperty property = (ApplicationProperty) o;
        return key == property.key && value.equals(property.value);
    }

    public Key getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }

    @Override
    public int hashCode() {
        int result = key.hashCode();
        result = 31 * result + value.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return ApplicationProperty.class.getSimpleName() + '{' +
               "key=" + key +
               ", value='" + value + '\'' +
               '}';
    }

    /**
     * Only DB stored, ApplicationProperties keys here. See also {@link com.atlassian.stash.internal.ApplicationConstants}
     */
    public enum Key {

        /* Name of the Stash instance, as it will appear in the user's browser */
        NAME("instance.name"),
        /* The active AvatarSource for the ConfigurableAvatarService */
        AVATAR_SOURCE("avatar.source"),
        /* Base URL used for self-referential links (used for email notifications, etc.) */
        BASE_URL("instance.url"),
        /* Email address sets as the sender's address in email notifications */
        EMAIL_ADDRESS("mail.sender.address"),
        /* Path to the STASH_HOME used on last server start */
        LAST_HOME("instance.home"),
        /* License string */
        LICENSE("license"),
        /* The time the license was first exceeded */
        LICENSE_EXCEEDED_GRACE_PERIOD_START("license.exceeded.grace.period.start"),
        LOCALE("locale"),
        MODE("instance.application.mode"),
        /* Server ID */
        SERVER_ID("server.id"),
        /* Default timezone for user date rendering */
        SERVER_TIMEZONE("server.tz"),

        /* Mail host settings */
        MAIL_HOST("mail.host"),
        MAIL_HOST_PORT("mail.port"),
        MAIL_HOST_USERNAME("mail.username"),
        MAIL_HOST_PASSWORD("mail.password"),
        MAIL_PROTOCOL("mail.protocol"),
        MAIL_USE_TLS("mail.useTls"),
        MAIL_REQUIRE_TLS("mail.requireTls"),

        /* Authentication settings */
        ALLOW_PUBLIC_SIGNUP("auth.public.signup"),
        REQUIRE_CAPTCHA_ON_SIGNUP("auth.captcha.signup"),
        MAX_CAPTCHA_ATTEMPTS("auth.max.captcha"),

        /* Whether the setup wizard has been completed */
        SETUP_COMPLETED("setup.completed"),

        /* Support settings */
        DEBUG_LOGGING_ENABLED("logging.debug.enabled"),
        PROFILING_ENABLED("profiling.enabled"),

        /* Whether SCM access is enabled over HTTP(S) */
        HTTP_SCM_HOSTING_ENABLED("scm.http.enabled");

        private final String id;

        Key(String id) {
            this.id = id;
        }

        // used by the GenericEnumUserType
        public String getId() {
            return id;
        }

        // used by the GenericEnumUserType
        public static Key fromId(String id) {
            for (Key key : values()) {
                if (key.id.equals(id)) {
                    return key;
                }
            }
            throw new IllegalArgumentException("No ApplicationProperty.Key matches the ID [" + id + ']');
        }
    }
}
