/*
 * 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.camel.component.as2.api;

import java.security.Key;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.http.entity.ContentType;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.SignerInfoGenerator;
import org.bouncycastle.cms.SignerInformation;

public class AS2SignedDataGenerator extends CMSSignedDataGenerator {

    public static final Map<ASN1ObjectIdentifier, String> STANDARD_MICALGS;

    static {
        Map<ASN1ObjectIdentifier, String> stdMicAlgs = new HashMap<>();

        stdMicAlgs.put(CMSAlgorithm.MD5, "md5");
        stdMicAlgs.put(CMSAlgorithm.SHA1, "sha-1");
        stdMicAlgs.put(CMSAlgorithm.SHA224, "sha-224");
        stdMicAlgs.put(CMSAlgorithm.SHA256, "sha-256");
        stdMicAlgs.put(CMSAlgorithm.SHA384, "sha-384");
        stdMicAlgs.put(CMSAlgorithm.SHA512, "sha-512");
        stdMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94");
        stdMicAlgs.put(CMSAlgorithm.GOST3411_2012_256, "gostr3411-2012-256");
        stdMicAlgs.put(CMSAlgorithm.GOST3411_2012_512, "gostr3411-2012-512");

        STANDARD_MICALGS = Collections.unmodifiableMap(stdMicAlgs);
    }

    /**
     * Signing algorithms for DSA keys in order of preference
     */
    public static final String[] DSA_SIGNING_ALGORITHMS = {
    "SHA512WITHDSA",
    "SHA384WITHDSA",
    "SHA256WITHDSA",
    "SHA224WITHDSA",
    "SHA1WITHDSA",
    };

    /**
     * Signing algorithms for RSA keys in order of preference
     */
    public static final String[] RSA_SIGNING_ALGORITHMS = {
    "SHA512WITHRSA",
    "SHA384WITHRSA",
    "SHA256WITHRSA",
    "SHA224WITHRSA",
    "SHA1WITHRSA",
    "MD5WITHRSA",
    "MD2WITHRSA",
    };

    /**
     * Signing algorithms for EC keys in order of preference
     */
    public static final String[] EC_SIGNING_ALGORITHMS = {
    "SHA512WITHECDSA",
    "SHA384WITHECDSA",
    "SHA256WITHECDSA",
    "SHA224WITHECDSA",
    "SHA1WITHECDSA",
    };

    public AS2SignedDataGenerator() {
    }

    /**
     * Creates a <code>multipart/signed</code> content type containing the algorithms used by this generator.
     *
     * @param boundary - boundary to use to demarcate content.
     * @return A <code>multipart/signed</code> content type
     */
    public ContentType createMultipartSignedContentType(String boundary) {
        StringBuffer header = new StringBuffer(AS2MediaType.MULTIPART_SIGNED);
        header.append("; boundary=" + boundary);
        Set<String> micAlgSet = new HashSet<>();

        // Collect algorithm names used by pre-calculated signers
        for (@SuppressWarnings("rawtypes")
        Iterator it = _signers.iterator(); it.hasNext();) {
            SignerInformation signer = (SignerInformation) it.next();
            ASN1ObjectIdentifier digestOID = signer.getDigestAlgorithmID().getAlgorithm();

            String micAlg = STANDARD_MICALGS.get(digestOID);

            if (micAlg == null) {
                micAlgSet.add("unknown");
            } else {
                micAlgSet.add(micAlg);
            }
        }

        // Collect algorithm names used by signer generators
        for (@SuppressWarnings("rawtypes")
        Iterator it = signerGens.iterator(); it.hasNext();) {
            SignerInfoGenerator signerInfoGen = (SignerInfoGenerator) it.next();
            ASN1ObjectIdentifier digestOID = signerInfoGen.getDigestAlgorithm().getAlgorithm();

            String micAlg = STANDARD_MICALGS.get(digestOID);

            if (micAlg == null) {
                micAlgSet.add("unknown");
            } else {
                micAlgSet.add(micAlg);
            }
        }

        // Add algorithm names to multipart signed header.
        int count = 0;
        for (String micAlg : micAlgSet) {
            if (count == 0) {
                if (micAlgSet.size() != 1) {
                    header.append("; micalg=\"");
                } else {
                    header.append("; micalg=");
                }
            } else {
                header.append(',');
            }

            header.append(micAlg);

            count++;
        }

        if (count != 0) {
            if (micAlgSet.size() != 1) {
                header.append('\"');
            }
        }

        return ContentType.parse(header.toString());
    }

    public static String[] getSupportedSignatureAlgorithmNamesForKey(Key key) {

        switch (key.getAlgorithm()) {
        case "DSA":
            return DSA_SIGNING_ALGORITHMS;
        case "RSA":
            return RSA_SIGNING_ALGORITHMS;
        case "EC":
            return EC_SIGNING_ALGORITHMS;
        default:
            return new String[0];
        }
    }

}
