/**
 * 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.wss4j.dom;

/**
 * WSDocInfo holds information about the document to process. It provides a
 * method to store and access document information about BinarySecurityToken,
 * used Crypto, and others.
 *
 * Using the Document's hash a caller can identify a document and get
 * the stored information that me be necessary to process the document.
 * The main usage for this is (are) the transformation functions that
 * are called during Signature/Verification process.
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.crypto.dom.DOMCryptoContext;

import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.util.XMLUtils;
import org.apache.wss4j.dom.callback.CallbackLookup;
import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class WSDocInfo {
    private Document doc;
    private Crypto crypto;

    // Here we map the token "Id" to the token itself. The token "Id" is the key as it must be unique to guard
    // against various wrapping attacks. The "Id" name/namespace is stored as part of the entry (along with the
    // element), so that we know what namespace to use when setting the token on the crypto context for signature
    // creation or validation
    private final Map<String, TokenValue> tokens = new HashMap<>();

    private final List<WSSecurityEngineResult> results = new LinkedList<>();
    private final Map<Integer, List<WSSecurityEngineResult>> actionResults = new HashMap<>();
    private CallbackLookup callbackLookup;
    private Element securityHeader;

    public WSDocInfo(Document doc) {
        //
        // This is a bit of a hack. When the Document is a SAAJ SOAPPart instance, it may
        // be that the "owner" document of any child elements is an internal Document, rather
        // than the SOAPPart. This is the case for the SUN SAAJ implementation.
        //
        if (doc != null && doc.getDocumentElement() != null) {
            this.doc = doc.getDocumentElement().getOwnerDocument();
        } else {
            this.doc = doc;
        }
    }

    /**
     * Clears the data stored in this object
     */
    public void clear() {
        crypto = null;
        doc = null;
        callbackLookup = null;
        securityHeader = null;
        tokens.clear();
        results.clear();
        actionResults.clear();
    }

    /**
     * Store a token element for later retrieval. Before storing the token, we check for a
     * previously processed token with the same (wsu/SAML) Id.
     * @param element is the token element to store
     */
    public void addTokenElement(Element element) throws WSSecurityException {
        addTokenElement(element, true);
    }

    /**
     * Store a token element for later retrieval. Before storing the token, we check for a
     * previously processed token with the same (wsu/SAML) Id.
     * @param element is the token element to store
     * @param checkMultipleElements check for a previously stored element with the same Id.
     */
    public void addTokenElement(Element element, boolean checkMultipleElements) throws WSSecurityException {
        if (element == null) {
            return;
        }

        if (element.hasAttributeNS(WSConstants.WSU_NS, "Id")) {
            String id = element.getAttributeNS(WSConstants.WSU_NS, "Id");
            TokenValue tokenValue = new TokenValue("Id", WSConstants.WSU_NS, element);
            TokenValue previousValue = tokens.put(id, tokenValue);
            if (checkMultipleElements && previousValue != null) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "duplicateError"
                );
            }
        }

        if (element.hasAttributeNS(null, "Id")) {
            String id = element.getAttributeNS(null, "Id");
            TokenValue tokenValue = new TokenValue("Id", null, element);
            TokenValue previousValue = tokens.put(id, tokenValue);
            if (checkMultipleElements && previousValue != null) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "duplicateError"
                );
            }
        }

        // SAML Assertions
        if ("Assertion".equals(element.getLocalName())) {
            if (WSConstants.SAML_NS.equals(element.getNamespaceURI())
                && element.hasAttributeNS(null, "AssertionID")) {
                String id = element.getAttributeNS(null, "AssertionID");
                TokenValue tokenValue = new TokenValue("AssertionID", null, element);
                TokenValue previousValue = tokens.put(id, tokenValue);
                if (checkMultipleElements && previousValue != null) {
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "duplicateError"
                    );
                }
            } else if (WSConstants.SAML2_NS.equals(element.getNamespaceURI())
                && element.hasAttributeNS(null, "ID")) {
                String id = element.getAttributeNS(null, "ID");
                TokenValue tokenValue = new TokenValue("ID", null, element);
                TokenValue previousValue = tokens.put(id, tokenValue);
                if (checkMultipleElements && previousValue != null) {
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "duplicateError"
                    );
                }
            }
        }

    }


    /**
     * Get a token Element for the given Id. The Id can be either a wsu:Id or a
     * SAML AssertionID/ID.
     * @param uri is the (relative) uri of the id
     * @return the token element or null if nothing found
     */
    public Element getTokenElement(String uri) {
        String id = XMLUtils.getIDFromReference(uri);
        if (id == null) {
            return null;
        }

        TokenValue token = tokens.get(id);
        if (token != null) {
            return token.getToken();
        }

        return null;
    }

    /**
     * Set all stored tokens on the DOMCryptoContext argument
     * @param context
     */
    public void setTokensOnContext(DOMCryptoContext context) {
        if (!tokens.isEmpty() && context != null) {
            for (Map.Entry<String, TokenValue> entry : tokens.entrySet()) {
                TokenValue tokenValue = entry.getValue();
                context.setIdAttributeNS(tokenValue.getToken(), tokenValue.getIdNamespace(),
                                         tokenValue.getIdName());
            }
        }
    }

    public void setTokenOnContext(String uri, DOMCryptoContext context) {
        String id = XMLUtils.getIDFromReference(uri);
        if (id == null || context == null) {
            return;
        }

        TokenValue tokenValue = tokens.get(id);
        if (tokenValue != null) {
            context.setIdAttributeNS(tokenValue.getToken(), tokenValue.getIdNamespace(),
                                     tokenValue.getIdName());
        }
    }


    /**
     * Store a WSSecurityEngineResult for later retrieval.
     * @param result is the WSSecurityEngineResult to store
     */
    public void addResult(WSSecurityEngineResult result) {
        results.add(result);
        Integer resultTag = (Integer)result.get(WSSecurityEngineResult.TAG_ACTION);
        if (resultTag != null) {
            List<WSSecurityEngineResult> storedResults = actionResults.get(resultTag);
            if (storedResults == null) {
                storedResults = new ArrayList<>();
            }
            storedResults.add(result);
            actionResults.put(resultTag, storedResults);
        }
    }

    /**
     * Get a copy of the security results list. Modifying the subsequent list does not
     * change the internal results list.
     */
    public List<WSSecurityEngineResult> getResults() {
        if (results.isEmpty()) {
            return Collections.emptyList();
        }
        return new ArrayList<>(results);
    }

    /**
     * Return a copy of the map between security actions + results. Modifying the subsequent
     * map does not change the internal map.
     */
    public Map<Integer, List<WSSecurityEngineResult>> getActionResults() {
        if (actionResults.isEmpty()) {
            return Collections.emptyMap();
        }
        return new HashMap<>(actionResults);
    }

    /**
     * Get a WSSecurityEngineResult for the given Id.
     * @param uri is the (relative) uri of the id
     * @return the WSSecurityEngineResult or null if nothing found
     */
    public WSSecurityEngineResult getResult(String uri) {
        String id = XMLUtils.getIDFromReference(uri);
        if (id == null) {
            return null;
        }

        if (!results.isEmpty()) {
            for (WSSecurityEngineResult result : results) {
                String cId = (String)result.get(WSSecurityEngineResult.TAG_ID);
                if (id.equals(cId)) {
                    return result;
                }
            }
        }
        return null;
    }

    /**
     * Get a unmodifiable list of WSSecurityEngineResults of the given Integer tag
     */
    public List<WSSecurityEngineResult> getResultsByTag(Integer tag) {
        if (actionResults.isEmpty() || !actionResults.containsKey(tag)) {
            return Collections.emptyList();
        }

        return Collections.unmodifiableList(actionResults.get(tag));
    }

    /**
     * See whether we have a WSSecurityEngineResult of the given Integer tag for the given Id
     */
    public boolean hasResult(Integer tag, String uri) {
        String id = XMLUtils.getIDFromReference(uri);
        if (id == null || "".equals(uri)) {
            return false;
        }

        if (!actionResults.isEmpty() && actionResults.containsKey(tag)) {
            for (WSSecurityEngineResult result : actionResults.get(tag)) {
                String cId = (String)result.get(WSSecurityEngineResult.TAG_ID);
                if (id.equals(cId)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * @return the signature crypto class used to process
     *         the signature/verify
     */
    public Crypto getCrypto() {
        return crypto;
    }

    /**
     * @return the document
     */
    public Document getDocument() {
        return doc;
    }

    /**
     * @param crypto is the signature crypto class used to
     *               process signature/verify
     */
    public void setCrypto(Crypto crypto) {
        this.crypto = crypto;
    }

    /**
     * @param callbackLookup The CallbackLookup object to retrieve elements
     */
    public void setCallbackLookup(CallbackLookup callbackLookup) {
        this.callbackLookup = callbackLookup;
    }

    /**
     * @return the CallbackLookup object to retrieve elements
     */
    public CallbackLookup getCallbackLookup() {
        return callbackLookup;
    }

    /**
     * @return the wsse header being processed
     */
    public Element getSecurityHeader() {
        return securityHeader;
    }

    /**
     * Sets the wsse header being processed
     *
     * @param securityHeader
     */
    public void setSecurityHeader(Element securityHeader) {
        this.securityHeader = securityHeader;
    }

    private static class TokenValue {
        private final String idName;
        private final String idNamespace;
        private final Element token;

        TokenValue(String idName, String idNamespace, Element token) {
            this.idName = idName;
            this.idNamespace = idNamespace;
            this.token = token;
        }

        public String getIdName() {
            return idName;
        }

        public String getIdNamespace() {
            return idNamespace;
        }
        public Element getToken() {
            return token;
        }
    }

}
