/*-
 * ~~~~~~licensing~~~~~~
 * core-support-runtime
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.core.support.runtime.cxf;

import org.apache.cxf.common.security.SimpleGroup;
import org.apache.cxf.common.security.SimplePrincipal;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.apache.cxf.rt.security.claims.Claim;
import org.apache.cxf.rt.security.claims.ClaimCollection;
import org.apache.cxf.rt.security.claims.ClaimsSecurityContext;

import javax.security.auth.Subject;
import java.security.Principal;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ExtJwtTokenSecurityContext implements ClaimsSecurityContext {
	private final JwtToken token;
    private final Principal principal;
    private final Set<Principal> roles;
    private final ClaimCollection claims = new ClaimCollection();

    public ExtJwtTokenSecurityContext(JwtToken jwt, String roleClaim, String regexp) {
        principal = new SimplePrincipal(jwt.getClaims().getSubject());
        this.token = jwt;
        if (roleClaim != null && jwt.getClaims().containsProperty(roleClaim)) {
            roles = new HashSet<>();
            String role = jwt.getClaims().getStringProperty(roleClaim).trim();
            //TODO Think to remove regexp cz it is heavy operation
            for (String r : role.split(regexp)) {
                roles.add(new SimpleGroup(r));
            }
        } else {
            roles = Collections.emptySet();
        }

        // Parse JwtToken into ClaimCollection
        jwt.getClaims().asMap().forEach((String name, Object values) -> {
            Claim claim = new Claim();
            claim.setClaimType(name);
            if (values instanceof List<?>) {
                claim.setValues(CastUtils.cast((List<?>)values));
            } else {
                claim.setValues(Collections.singletonList(values));
            }
            claims.add(claim);
        });
    }

    public JwtToken getToken() {
        return token;
    }

    @Override
    public Subject getSubject() {
        return null;
    }

    @Override
    public Set<Principal> getUserRoles() {
        return Collections.unmodifiableSet(roles);
    }

    @Override
    public Principal getUserPrincipal() {
        return principal;
    }

    @Override
    public boolean isUserInRole(String role) {
        for (Principal principalRole : roles) {
            if (principalRole != principal && principalRole.getName().equals(role)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public ClaimCollection getClaims() {
        return claims;
    }

}
