package org.kuorum.service.mailing.send.builder.thymeleaf;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.thymeleaf.Arguments;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.exceptions.ConfigurationException;
import org.thymeleaf.messageresolver.AbstractMessageResolver;
import org.thymeleaf.messageresolver.MessageResolution;
import org.thymeleaf.util.Validate;

/**
 * This class is equals to SpringMessageResolver but without 'MessageSourceAware' because the
 * messageSource is set on spring configuration.
 */
public class ThymeLeafSpringMessageResolver
        extends AbstractMessageResolver {


    private static final Logger logger = LoggerFactory.getLogger(ThymeLeafSpringMessageResolver.class);


    private MessageSource messageSource;


    public ThymeLeafSpringMessageResolver() {
        super();
    }





    @Override
    protected final void initializeSpecific() {

        /*
         * Check the application context has been set.
         */
        if (this.messageSource == null) {
            throw new ConfigurationException(
                    "Cannot initialize " + ThymeLeafSpringMessageResolver.class.getSimpleName() +
                            ": MessageSource has not been set. Either define this object as " +
                            "a Spring bean (which will automatically set the MessageSource) or, " +
                            "if you instance it directly, set the MessageSource manually using its "+
                            "corresponding setter method.");
        }

    }





    /**
     * <p>
     *   Returns the message source ({@link MessageSource}) to be
     *   used for message resolution.
     * </p>
     *
     * @return the message source
     */
    public final MessageSource getMessageSource() {
        checkInitialized();
        return this.messageSource;
    }


    /**
     * <p>
     *   Uninitialized method meant for use by subclasses.
     * </p>
     *
     * @return the message source
     */
    protected final MessageSource unsafeGetMessageSource() {
        return this.messageSource;
    }


    /**
     * <p>
     *   Sets the message source to be used for message resolution
     * </p>
     *
     * @param messageSource the message source
     */
    public final void setMessageSource(final MessageSource messageSource) {
        checkNotInitialized();
        this.messageSource = messageSource;
    }





    public MessageResolution resolveMessage(
            final Arguments arguments, final String key, final Object[] messageParameters) {

        Validate.notNull(arguments, "Arguments cannot be null");
        Validate.notNull(arguments.getContext().getLocale(), "Locale in context cannot be null");
        Validate.notNull(key, "Message key cannot be null");

        if (logger.isTraceEnabled()) {
            logger.trace("[THYMELEAF][{}] Resolving message with key \"{}\" for template \"{}\" and locale \"{}\". Messages will be retrieved from Spring's MessageSource infrastructure.", new Object[] {TemplateEngine.threadIndex(), key, arguments.getTemplateName(), arguments.getContext().getLocale()});
        }

        try {

            final String resolvedMessage =
                    this.messageSource.getMessage(key, messageParameters, arguments.getContext().getLocale());

            return new MessageResolution(resolvedMessage);

        } catch (NoSuchMessageException e) {
            return null;
        }

    }

}
