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

import com.atlassian.soy.renderer.JsExpression;
import com.atlassian.soy.renderer.SanitizedString;
import com.atlassian.soy.renderer.SoyClientFunction;
import com.atlassian.soy.renderer.SoyServerFunction;
import com.atlassian.stash.internal.web.fragments.WebFragmentSupport;
import com.atlassian.stash.internal.web.fragments.WebPanelData;

import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.atlassian.stash.internal.web.soy.functions.SoyArgumentUtils.argCountFromTo;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.stream.Collectors.toList;

public class WebPanelFunction implements SoyServerFunction<List<SanitizedString>>, SoyClientFunction {

    private static final Set<Integer> VALID_ARG_SIZES = argCountFromTo(1, 2);
    private final WebFragmentSupport webFragmentSupport;

    public WebPanelFunction(WebFragmentSupport webFragmentSupport) {
        this.webFragmentSupport = webFragmentSupport;
    }

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

    @Override
    public JsExpression generate(JsExpression... args) {
        checkArgument(VALID_ARG_SIZES.contains(args.length), "invalid number of arguments: %s", args.length);
        return new JsExpression("WebFragments.getWebPanels(" +
                                args[0].getText() +
                                (args.length > 1 ? "," + args[1].getText() : "") +
                                ").map(function(webPanel) { return soydata.VERY_UNSAFE.ordainSanitizedHtml(webPanel); })");
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<SanitizedString> apply(Object... args) {
        checkArgument(VALID_ARG_SIZES.contains(args.length), "invalid number of arguments: %s", args.length);
        String location = (String) args[0];
        Map<String, Object> context = null;
        if (args.length == 2) {
            context = (Map<String, Object>) args[1];
        }
        return webFragmentSupport.getWebPanels(location, context, false)
                .stream()
                .map(WebPanelData::getHtml)
                .map(SanitizedString::new)
                .collect(toList());
    }

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