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

import com.atlassian.bitbucket.help.HelpPathService;
import com.atlassian.soy.renderer.JsExpression;
import com.atlassian.soy.renderer.SoyClientFunction;
import com.atlassian.soy.renderer.SoyServerFunction;
import com.google.common.base.Preconditions;

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

import static com.atlassian.stash.internal.web.soy.functions.SoyArgumentUtils.argCountOf;

public class HelpUrlFunction implements SoyServerFunction<String>, SoyClientFunction {
    private static final Set<Integer> VALID_ARG_SIZES = argCountOf(1);
    private static final Pattern LITERAL_PATTERN = Pattern.compile("'(\\\\.|[^'])*'");

    private final HelpPathService helpPathService;

    public HelpUrlFunction(HelpPathService helpPathService) {
        this.helpPathService = helpPathService;
    }

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

    @Override
    public JsExpression generate(JsExpression... jsExpressions) {
        Preconditions.checkArgument(jsExpressions.length == 1, "Wrong number of arguments (1 expected)");
        Preconditions.checkArgument(LITERAL_PATTERN.matcher(jsExpressions[0].getText()).matches(), "The first argument, the help key name, should be a string literal");

        return new JsExpression("bitbucket_help_url(" + jsExpressions[0].getText() + ")");
    }

    @Override
    public String apply(Object... args) {
        Preconditions.checkArgument(args.length == 1, "Wrong number of arguments (1 expected)");
        Preconditions.checkArgument(args[0] instanceof String, "The first argument, the help key name, should be a string");

        String helpPageUrl = helpPathService.getPageUrl((String) args[0]);
        return helpPageUrl == null ? "" : helpPageUrl;
    }

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