/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
var certificateChainTest = {

  /**
   * Validates a certificate chain that was generated using Java.
   *
   * @param {String}
   *            rootCertificatePem the root certificate, in PEM format.
   * @param {String}
   *            intermediateCertificatePem the intermediate certificate, in
   *            PEM format.
   * @param {String}
   *            leafCertificatePem the leaf certificate, in PEM format.
   * @param {Array}
   *            intermediateSubjectDnFields the intermediate certificate
   *            subject DN fields, as an array of Strings.
   * @param {Array}
   *            leafSubjectDnFields the leaf certificate subject DN fields, as
   *            an array of Strings.
   * @param {String}
   *            leafCertifiateType the leaf certificate type.
   * @param {String}
   *            leafTimeReference the leaf certificate time reference, in
   *            Epoch time format.
   * @throws {Error}
   *             if the certificate chain validation fails.
   */
  validate: function(
      rootCertificatePem, intermediateCertificatePem, leafCertificatePem,
      intermediateSubjectDnFields, leafSubjectDnFields, leafCertificateType,
      leafTimeReference) {

    'use strict';

    intermediateSubjectDnFields = Java.from(intermediateSubjectDnFields);
    leafSubjectDnFields = Java.from(leafSubjectDnFields);

    var errorData = {};
    errorData['Root certificate (PEM format) [Java]'] = rootCertificatePem;
    errorData['Intermediate certificate (PEM format) [Java]'] =
        intermediateCertificatePem;
    errorData['Leaf certificate (PEM format) [Java]'] = leafCertificatePem;
    errorData['Intermediate certificate subject DN fields [Java]'] =
        intermediateSubjectDnFields;
    errorData['Leaf certificate subject DN fields [Java]'] =
        leafSubjectDnFields;
    errorData['Leaf certificate type [Java]'] = leafCertificateType;
    errorData['Leaf certificate time reference (Epoch time format) [Java]'] =
        leafTimeReference;

    try {
      cryptolib('certificates.service', function(box) {

        var leafTimeReferenceAsDate =
            testUtils.epochTimeStringToDate(leafTimeReference);

        var certificateChain = {
          root: rootCertificatePem,
          certificates: {
            pems: [intermediateCertificatePem],
            subjects: [{
              commonName: intermediateSubjectDnFields[0],
              country: intermediateSubjectDnFields[1],
              organizationUnit: intermediateSubjectDnFields[2],
              organization: intermediateSubjectDnFields[3]
            }]
          },
          leaf: {
            pem: leafCertificatePem,
            subject: {
              commonName: leafSubjectDnFields[0],
              country: leafSubjectDnFields[1],
              organizationUnit: leafSubjectDnFields[2],
              organization: leafSubjectDnFields[3]
            },
            keyType: leafCertificateType,
            time: leafTimeReferenceAsDate.toISOString()
          }
        };

        var validationResult =
            box.certificates.service.validateX509CertificateChain(
                certificateChain);
        var validationResultAsArray =
            box.certificates.service.flattenFailedValidations(validationResult);

        var numFailedValidations = validationResultAsArray.length;
        if (numFailedValidations > 0) {
          for (var i = 0; i < numFailedValidations; i++) {
            errorData['Failed certificate chain validation ' + i.toString()] =
                validationResultAsArray[i];
          }

          throw 'Validation of certificate chain failed.';
        }
      });
    } catch (error) {
      throw testUtils.serializeError(error, errorData);
    }
  }
};