package com.atlassian.stash.internal.web;

import com.atlassian.plugin.servlet.DownloadableResource;
import com.atlassian.plugin.webresource.QueryParams;
import com.atlassian.plugin.webresource.transformer.*;
import com.atlassian.plugin.webresource.url.UrlBuilder;
import com.atlassian.stash.internal.util.InternalDateFormatter;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StashDateFormatWebResourceTransformer implements WebResourceTransformerFactory,
        TransformerUrlBuilder, UrlReadingWebResourceTransformer {

    private static final Pattern PATTERN = Pattern.compile(
            "date_format" +
                    "\\(\\s*" +                  // start paren
                    "(['\"])([\\w.-]+)\\1" +     // single or double quoted key-style word
                    "\\s*\\)");                  // end paren

    private final InternalDateFormatter dateFormatter;

    public StashDateFormatWebResourceTransformer(InternalDateFormatter dateFormatter) {
        this.dateFormatter = dateFormatter;
    }

    @Override
    public TransformerUrlBuilder makeUrlBuilder(TransformerParameters parameters) {
        return this;
    }

    @Override
    public UrlReadingWebResourceTransformer makeResourceTransformer(TransformerParameters parameters) {
        return this;
    }

    @Override
    public void addToUrl(UrlBuilder urlBuilder) {
        urlBuilder.addToHash("dateFormats", dateFormatter.getStateHash());
    }

    @Override
    public DownloadableResource transform(TransformableResource transformableResource, QueryParams params) {
        return new CharSequenceDownloadableResource(transformableResource.nextResource()) {
            @Override
            protected CharSequence transform(CharSequence original) {
                return doTransform(original);
            }
        };
    }

    @VisibleForTesting
    String doTransform(CharSequence originalContent) {
        Matcher matcher = PATTERN.matcher(originalContent);

        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            String formatString = dateFormatter.getFormatString(matcher.group(2));

            matcher.appendReplacement(result, "");
            result
                    .append("'")
                    .append(StringEscapeUtils.escapeEcmaScript(StringUtils.defaultString(formatString)))
                    .append("'");
        }
        matcher.appendTail(result);

        return result.toString();
    }

}
