package be.iminds.ilabt.jfed.scanner;

import java.security.PrivateKey;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * AuthorityScannerInput
 */
public class AuthorityScannerInput {
    //package public
    final List<String> urns; //supports various urns: +user+ +authority+cm  +am   +sa etc
    final Set<String> urls;
    final Set<X509Certificate> trustedCerts;
    final List<X509Certificate> userCerts;
    final PrivateKey userPrivateKey;
    final AuthorityType type;
    final boolean userIsOfScannedAuthority;

    public AuthorityScannerInput(List<String> urns, List<String> urls, List<X509Certificate> trustedCerts, List<X509Certificate> userCerts, PrivateKey userPrivateKey, AuthorityType type, boolean userIsOfScannedAuthority) {
//        this.urns = Collections.unmodifiableList(urns); //?
        this.urns = urns;
        this.urls = new HashSet<>(urls);
        this.trustedCerts = new HashSet<>(trustedCerts);
        this.userCerts = userCerts;
        this.userPrivateKey = userPrivateKey;
        this.type = type;
        this.userIsOfScannedAuthority = userIsOfScannedAuthority;

        if (userIsOfScannedAuthority)
            userCerts.forEach(this::findInUserCerts);
    }

    public void findInAltNames(Collection<List<?>> altNames) {
        if (altNames != null && !altNames.isEmpty()) {

            for (List<?> altName : altNames) {
                Integer nameType = (Integer) altName.get(0);
                if (nameType == 6) {
                    //uniformResourceIdentifier
                    String urn = (String) altName.get(1);
                    urns.add(urn);
                } else {
                    String v = (String) altName.get(1);
                    if (v.startsWith("http")) urls.add(v);
                    if (v.startsWith("urn:")) urns.add(v);
                }
            }
        }
    }

    public void findInUserCerts(X509Certificate cert) {
        try {
            findInAltNames(cert.getSubjectAlternativeNames());
            findInAltNames(cert.getIssuerAlternativeNames());
        } catch (CertificateParsingException e) {
            //ignore subject Alt name parsing exceptions
        }
    }
}
