package cz.muni.ics.oidc.server.claims.sources;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import cz.muni.ics.oauth2.model.SamlAuthenticationDetails;
import cz.muni.ics.oidc.server.claims.ClaimSourceInitContext;
import cz.muni.ics.oidc.server.claims.ClaimSourceProduceContext;
import cz.muni.ics.oidc.server.claims.ClaimUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * Extension of the EntitlementSource to merge configured SAML attribute with the computed values.
 * Configuration (replace [claimName] with the name of the claim):
 * @see EntitlementSource
 * <ul>
 *     <li><b>custom.claim.[claimName].source.samlEntitlementsAttrName</b> - OID/attribute name representing
 *            the entitlements forwarded from SAML</li>
 * </ul>
 *
 * @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
 */
@Slf4j
public class EntitlementPlusSamlForwardedClaimSource extends EntitlementSource {

	protected static final String SAML_ENTITLEMENTS_ATTR_NAME = "samlEntitlementsAttrName";

	private final String samlEntitlementsAttrName;

	public EntitlementPlusSamlForwardedClaimSource(ClaimSourceInitContext ctx) {
		super(ctx);

		this.samlEntitlementsAttrName = ClaimUtils.fillStringMandatoryProperty(
				SAML_ENTITLEMENTS_ATTR_NAME, ctx, ctx.getClaimName());
		log.debug("{} - samlEntitlementsAttrName: '{}'", getClaimName(), samlEntitlementsAttrName);
	}

	@Override
	public Set<String> getAttrIdentifiers() {
		return super.getAttrIdentifiers();
	}

	@Override
	public JsonNode produceValue(ClaimSourceProduceContext pctx) {
		JsonNode entitlements = super.produceValue(pctx);
		JsonNode result = ClaimUtils.produceSamlMergedEntitlements(pctx, entitlements, samlEntitlementsAttrName);
		log.debug("{} - produced value for user({}): '{}'", getClaimName(), pctx.getPerunUserId(), result);
		return result;
	}

}
