package com.atlassian.stash.internal.web.soy.functions;

import com.atlassian.bitbucket.server.StandardFeature;
import com.atlassian.bitbucket.server.FeatureManager;
import com.atlassian.soy.renderer.JsExpression;
import com.atlassian.soy.renderer.SoyClientFunction;
import com.atlassian.soy.renderer.SoyServerFunction;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringEscapeUtils;

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

public class IsFeatureEnabledFunction implements SoyServerFunction<Boolean>, SoyClientFunction {

    private static final Pattern LITERAL_STRING = Pattern.compile("^'(.*)'$");

    private static final Set<Integer> VALID_ARGS = ImmutableSet.of(1);

    private final FeatureManager featureManager;

    public IsFeatureEnabledFunction(FeatureManager featureManager) {
        this.featureManager = featureManager;
    }

    @Override
    public Boolean apply(Object... args) {
        String featureKey = SoyArgumentUtils.getStringArgument(args, 0);
        StandardFeature feature = StandardFeature.fromKey(featureKey);

        return featureManager.isEnabled(feature);
    }

    @Override
    public JsExpression generate(JsExpression... args) {
        JsExpression featureKeyAsStringLiteral = args[0];
        Matcher matcher = LITERAL_STRING.matcher(featureKeyAsStringLiteral.getText());
        if (!matcher.matches()) {
            throw new IllegalArgumentException(
                    "Argument to isFeatureEnabled() is not a literal string: " + featureKeyAsStringLiteral.getText());
        }
        String featureKey = StringEscapeUtils.unescapeEcmaScript(matcher.group(1));
        StandardFeature feature = StandardFeature.fromKey(featureKey);

        return new JsExpression(Boolean.toString(featureManager.isEnabled(feature)));
    }

    @Override
    public String getName() {
        return "isFeatureEnabled";
    }

    @Override
    public Set<Integer> validArgSizes() {
        return VALID_ARGS;
    }
}
