/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.cxf.fediz.core;


import java.net.URI;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.security.auth.callback.CallbackHandler;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.wss4j.common.saml.SAMLCallback;
import org.apache.wss4j.common.saml.bean.ActionBean;
import org.apache.wss4j.common.saml.bean.AttributeBean;
import org.apache.wss4j.common.saml.bean.AttributeStatementBean;
import org.apache.wss4j.common.saml.bean.AuthDecisionStatementBean;
import org.apache.wss4j.common.saml.bean.AuthenticationStatementBean;
import org.apache.wss4j.common.saml.bean.ConditionsBean;
import org.apache.wss4j.common.saml.bean.KeyInfoBean;
import org.apache.wss4j.common.saml.bean.KeyInfoBean.CERT_IDENTIFIER;
import org.apache.wss4j.common.saml.bean.SubjectBean;
import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
import org.apache.wss4j.common.saml.bean.SubjectLocalityBean;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.message.WSSecEncryptedKey;


/**
 * A base implementation of a Callback Handler for a SAML assertion. By default it creates an
 * authentication assertion.
 */
public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
    
    public enum Statement {
        AUTHN, ATTR, AUTHZ
    };
    
    public enum MultiValue {
        MULTI_VALUE, MULTI_ATTR, ENC_VALUE
    };
    
    public static final URI CLAIM_TYPE_LANGUAGE = 
        URI.create("http://schemas.mycompany.com/claims/language");
    
    protected String subjectName;
    protected String subjectQualifier;
    protected String confirmationMethod;
    protected X509Certificate[] certs;
    protected Statement statement = Statement.AUTHN;
    protected boolean alsoAddAuthnStatement;
    protected CERT_IDENTIFIER certIdentifier = CERT_IDENTIFIER.X509_CERT;
    protected byte[] ephemeralKey;
    protected String issuer;
    protected String subjectNameIDFormat;
    protected String subjectLocalityIpAddress;
    protected String subjectLocalityDnsAddress;
    protected String resource;
    protected List<?> customAttributeValues;
    protected ConditionsBean conditions;
    protected SubjectConfirmationDataBean subjectConfirmationData;
    protected List<String> roles = Arrays.asList("User", "Admin");
    protected Map<String, String> claims;
    protected MultiValue multiValueType = MultiValue.MULTI_VALUE;
    protected String roleSeperator = ",";
    protected String roleAttributeName = FedizConstants.DEFAULT_ROLE_URI.toString();
    protected String countryClaimName = ClaimTypes.COUNTRY.toString();
    protected String customClaimName = CLAIM_TYPE_LANGUAGE.toString();
    protected String attributeNameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified";
    protected boolean useNameFormatAsNamespace;
    
    public void setSubjectConfirmationData(SubjectConfirmationDataBean subjectConfirmationData) {
        this.subjectConfirmationData = subjectConfirmationData;
    }
    
    public void setConditions(ConditionsBean conditionsBean) {
        this.conditions = conditionsBean;
    }
    
    public void setConfirmationMethod(String confMethod) {
        confirmationMethod = confMethod;
    }
    
    public void setStatement(Statement statement) {
        this.statement = statement;
    }
    
    public void setCertIdentifier(CERT_IDENTIFIER certIdentifier) {
        this.certIdentifier = certIdentifier;
    }
    
    public void setCerts(X509Certificate[] certs) {
        this.certs = certs;
    }
    
    public byte[] getEphemeralKey() {
        return ephemeralKey;
    }
    
    public void setIssuer(String issuer) {
        this.issuer = issuer;
    }
    
    public void setSubjectNameIDFormat(String subjectNameIDFormat) {
        this.subjectNameIDFormat = subjectNameIDFormat;
    }
    
    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }
    
    public void setSubjectLocality(String ipAddress, String dnsAddress) {
        this.subjectLocalityIpAddress = ipAddress;
        this.subjectLocalityDnsAddress = dnsAddress;
    }
    
    public void setResource(String resource) {
        this.resource = resource;
    }
    
    public void setCustomAttributeValues(List<?> customAttributeValues) {
        this.customAttributeValues = customAttributeValues;
    }
    
    public void setRoles(List<String> roles) {
        this.roles = roles;
    }

    public void setClaims(Map<String, String> claims) {
        this.claims = claims;
    }

    public void setMultiValueType(MultiValue multiValueType) {
        this.multiValueType = multiValueType;
    }
    
    public void setRoleAttributeName(String roleAttributeName) {
        this.roleAttributeName = roleAttributeName;
    }
    
    public String getRoleAttributeName() {
        return this.roleAttributeName;
    }
    
    public void setCountryClaimName(String countryClaimName) {
        this.countryClaimName = countryClaimName;
    }
    
    public String getCountryClaimName() {
        return this.countryClaimName;
    }

    public void setCustomClaimName(String customClaimName) {
        this.customClaimName = customClaimName;
    }
    
    public String getCustomClaimName() {
        return this.customClaimName;
    }

    public void setAttributeNameFormat(String attributeNameFormat) {
        this.attributeNameFormat = attributeNameFormat;
    }
    
    public String getAttributeNameFormat() {
        return this.attributeNameFormat;
    }
    
    public boolean isUseNameFormatAsNamespace() {
        return useNameFormatAsNamespace;
    }

    public void setUseNameFormatAsNamespace(boolean useNameFormatAsNamespace) {
        this.useNameFormatAsNamespace = useNameFormatAsNamespace;
    }

    /**
     * Note that the SubjectBean parameter should be null for SAML2.0
     */
    //CHECKSTYLE:OFF
    protected void createAndSetStatement(SubjectBean subjectBean, SAMLCallback callback) {
        if (alsoAddAuthnStatement || statement == Statement.AUTHN) {
            AuthenticationStatementBean authBean = new AuthenticationStatementBean();
            if (subjectBean != null) {
                authBean.setSubject(subjectBean);
            }
            if (subjectLocalityIpAddress != null || subjectLocalityDnsAddress != null) {
                SubjectLocalityBean subjectLocality = new SubjectLocalityBean();
                subjectLocality.setIpAddress(subjectLocalityIpAddress);
                subjectLocality.setDnsAddress(subjectLocalityDnsAddress);
                authBean.setSubjectLocality(subjectLocality);
            }
            authBean.setAuthenticationMethod("Password");
            callback.setAuthenticationStatementData(Collections.singletonList(authBean));
        }
        
        if (statement == Statement.ATTR) {
            AttributeStatementBean attrStateBean = new AttributeStatementBean();
            if (subjectBean != null) {
                attrStateBean.setSubject(subjectBean);
            }
            
            if (this.roles == null) {
                AttributeBean attributeBean = new AttributeBean();
                if (subjectBean != null) {
                    attributeBean.setSimpleName("name");
                    attributeBean.setQualifiedName("dummy-ns");
                } else {
                    attributeBean.setQualifiedName("dummy-ns");
                }
                attributeBean.addAttributeValue("myvalue");
                attrStateBean.setSamlAttributes(Collections.singletonList(attributeBean));
                callback.setAttributeStatementData(Collections.singletonList(attrStateBean));
                return;
            }
            
            List<AttributeBean> attributeList = new ArrayList<>();
                        
            if (this.multiValueType.equals(MultiValue.MULTI_VALUE)
                || this.multiValueType.equals(MultiValue.ENC_VALUE)) {
//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
//                AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
//                <saml:AttributeValue>Value1</saml:AttributeValue>
//                <saml:AttributeValue>Value2</saml:AttributeValue>
//              </saml:Attribute>
//                 or                
//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
//              AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
//              <saml:AttributeValue>Value1,Value2</saml:AttributeValue>
//            </saml:Attribute>
                AttributeBean attributeBean = new AttributeBean();
                if (subjectBean != null) {
                    // SAML 1.1
                    if (this.isUseNameFormatAsNamespace()) {
                        //Workaround for CXF-4484
                        attributeBean.setSimpleName(this.roleAttributeName);
                        //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                        attributeBean.setQualifiedName(ClaimTypes.URI_BASE.toString());
                    } else {
                        attributeBean.setSimpleName(getNameOfClaimType(this.roleAttributeName));
                        //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                        attributeBean.setQualifiedName(getNamespaceOfClaimType(this.roleAttributeName));
                    }
                } else {
                    // SAML 2.0
                    attributeBean.setQualifiedName(this.roleAttributeName);
                    attributeBean.setNameFormat(this.getAttributeNameFormat());
                }
                if (this.multiValueType.equals(MultiValue.MULTI_VALUE)) {
                    for (String role : roles) {
                        attributeBean.addAttributeValue(role);
                    }
                } else {
                    StringBuilder sb = new StringBuilder();
                    for (String role: roles) {
                        sb.append(role).append(this.roleSeperator);
                    }
                    String value = sb.substring(0, sb.length() - this.roleSeperator.length());
                    attributeBean.addAttributeValue(value);
                }
                attributeList.add(attributeBean);
            } else if (this.multiValueType.equals(MultiValue.MULTI_ATTR)) {
//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
//                AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
//                <saml:AttributeValue>Value1</saml:AttributeValue>
//              </saml:Attribute>
//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
//                AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
//                <saml:AttributeValue>Value2</saml:AttributeValue>
//              </saml:Attribute>
                
                //List<AttributeBean> attrBeans = new ArrayList<>();
                for (String role: roles) {
                    AttributeBean attributeBean = new AttributeBean();
                    if (subjectBean != null) {
                        // SAML 1.1
                        if (this.isUseNameFormatAsNamespace()) {
                            //Workaround for CXF-4484
                            attributeBean.setSimpleName(this.roleAttributeName);
                            //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                            attributeBean.setQualifiedName(ClaimTypes.URI_BASE.toString());
                        } else {
                            attributeBean.setSimpleName(getNameOfClaimType(this.roleAttributeName));
                            //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                            attributeBean.setQualifiedName(getNamespaceOfClaimType(this.roleAttributeName));
                        }
                    } else {
                        // SAML 2.0
                        attributeBean.setQualifiedName(this.roleAttributeName);
                        attributeBean.setNameFormat(this.getAttributeNameFormat());
                    }
                    attributeBean.addAttributeValue(role);
                    attributeList.add(attributeBean);
                }
            }
            
            //ClaimTypes.COUNTRY
            AttributeBean attributeBean = new AttributeBean();
            if (subjectBean != null) {
                //SAML 1.1
                attributeBean.setSimpleName(getNameOfClaimType(this.countryClaimName));
                //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                attributeBean.setQualifiedName(getNamespaceOfClaimType(this.countryClaimName));
                
            } else {
                //SAML 2.0
                attributeBean.setQualifiedName(this.countryClaimName);
                attributeBean.setNameFormat(this.getAttributeNameFormat());
            }
            attributeBean.addAttributeValue("CH");
            attributeList.add(attributeBean);
            
            //custom claim language
            AttributeBean attributeBean2 = new AttributeBean();
            if (subjectBean != null) {
                // SAML 1.1
                if (this.isUseNameFormatAsNamespace()) {
                    //Workaround for CXF-4484
                    attributeBean2.setSimpleName(this.customClaimName);
                    //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                    attributeBean2.setQualifiedName(ClaimTypes.URI_BASE.toString());
                } else {
                    attributeBean2.setSimpleName(getNameOfClaimType(this.customClaimName));
                    //QualifiedName maps to AttributeNamespace in SAML1ComponentBuilder.createSamlv1Attribute()
                    attributeBean2.setQualifiedName(getNamespaceOfClaimType(this.customClaimName));
                }
            } else {
                // SAML 2
                attributeBean2.setQualifiedName(this.customClaimName);
                attributeBean2.setNameFormat(this.getAttributeNameFormat());
            }
            if (customAttributeValues != null && !customAttributeValues.isEmpty()) {
                for (Object obj : customAttributeValues) {
                    attributeBean2.addAttributeValue(obj);
                }
            } else {
                attributeBean2.addAttributeValue("CH");
            }
            attributeList.add(attributeBean2);
            
            attrStateBean.setSamlAttributes(attributeList);
            callback.setAttributeStatementData(Collections.singletonList(attrStateBean));
                       
        } else if (statement == Statement.AUTHZ) {
            AuthDecisionStatementBean authzBean = new AuthDecisionStatementBean();
            if (subjectBean != null) {
                authzBean.setSubject(subjectBean);
            }
            ActionBean actionBean = new ActionBean();
            actionBean.setContents("Read");
            authzBean.setActions(Collections.singletonList(actionBean));
            authzBean.setResource("endpoint");
            authzBean.setDecision(AuthDecisionStatementBean.Decision.PERMIT);
            authzBean.setResource(resource);
            callback.setAuthDecisionStatementData(Collections.singletonList(authzBean));
        }
    }
    
    protected KeyInfoBean createKeyInfo() throws Exception {
        KeyInfoBean keyInfo = new KeyInfoBean();
        if (alsoAddAuthnStatement || statement == Statement.AUTHN) {
            keyInfo.setCertificate(certs[0]);
            keyInfo.setCertIdentifer(certIdentifier);
        } else if (statement == Statement.ATTR) {
            // Build a new Document
            DocumentBuilderFactory docBuilderFactory = 
                DocumentBuilderFactory.newInstance();
            docBuilderFactory.setNamespaceAware(true);
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
                  
            // Create an Encrypted Key
            WSSecEncryptedKey encrKey = new WSSecEncryptedKey();
            encrKey.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
            encrKey.setUseThisCert(certs[0]);
            encrKey.prepare(doc, null);
            ephemeralKey = encrKey.getEphemeralKey();
            Element encryptedKeyElement = encrKey.getEncryptedKeyElement();
            
            // Append the EncryptedKey to a KeyInfo element
            Element keyInfoElement = 
                doc.createElementNS(
                    WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
                );
            keyInfoElement.setAttributeNS(
                WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
            );
            keyInfoElement.appendChild(encryptedKeyElement);
            
            keyInfo.setElement(keyInfoElement);
        }
        return keyInfo;
    }
    
    protected String getNamespaceOfClaimType(String claimType) {
        int i = claimType.lastIndexOf("/");
        return claimType.substring(0, i);
    }
    
    protected String getNameOfClaimType(String claimType) {
        int i = claimType.lastIndexOf("/");
        return claimType.substring(i + 1);
    }
    
    public boolean isAlsoAddAuthnStatement() {
        return alsoAddAuthnStatement;
    }

    public void setAlsoAddAuthnStatement(boolean alsoAddAuthnStatement) {
        this.alsoAddAuthnStatement = alsoAddAuthnStatement;
    }
}
