"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.filterAndMapSdJwtKeys = filterAndMapSdJwtKeys;
exports.getCredentialForDisplay = getCredentialForDisplay;
var _core = require("@credo-ts/core");
var _decode = require("@sd-jwt/decode");
var _utils = require("./utils/utils");
var _metadata = require("./metadata");
function findDisplay(display) {
  if (!display) return undefined;
  let item = display.find(d => {
    var _d$locale;
    return (_d$locale = d.locale) === null || _d$locale === void 0 ? void 0 : _d$locale.startsWith('en-');
  });
  if (!item) item = display.find(d => !d.locale);
  if (!item) item = display[0];
  return item;
}
function getIssuerDisplay(metadata) {
  var _openidIssuerDisplay$, _openidIssuerDisplay$2;
  const issuerDisplay = {};
  // Try to extract from openid metadata first
  const openidIssuerDisplay = findDisplay(metadata === null || metadata === void 0 ? void 0 : metadata.issuer.display);
  issuerDisplay.name = openidIssuerDisplay === null || openidIssuerDisplay === void 0 ? void 0 : openidIssuerDisplay.name;
  issuerDisplay.logo = openidIssuerDisplay !== null && openidIssuerDisplay !== void 0 && openidIssuerDisplay.logo ? {
    url: (_openidIssuerDisplay$ = openidIssuerDisplay.logo) === null || _openidIssuerDisplay$ === void 0 ? void 0 : _openidIssuerDisplay$.url,
    altText: (_openidIssuerDisplay$2 = openidIssuerDisplay.logo) === null || _openidIssuerDisplay$2 === void 0 ? void 0 : _openidIssuerDisplay$2.alt_text
  } : undefined;

  // If the credentialDisplay contains a logo, and the issuerDisplay does not, use the logo from the credentialDisplay
  const openidCredentialDisplay = findDisplay(metadata === null || metadata === void 0 ? void 0 : metadata.credential.display);
  if (openidCredentialDisplay && !issuerDisplay.logo && openidCredentialDisplay.logo) {
    var _openidCredentialDisp, _openidCredentialDisp2;
    issuerDisplay.logo = {
      url: (_openidCredentialDisp = openidCredentialDisplay.logo) === null || _openidCredentialDisp === void 0 ? void 0 : _openidCredentialDisp.url,
      altText: (_openidCredentialDisp2 = openidCredentialDisplay.logo) === null || _openidCredentialDisp2 === void 0 ? void 0 : _openidCredentialDisp2.alt_text
    };
  }
  return issuerDisplay;
}
function processIssuerDisplay(metadata, issuerDisplay) {
  // Last fallback: use issuer id from openid4vc
  if (!issuerDisplay.name && metadata !== null && metadata !== void 0 && metadata.issuer.id) {
    issuerDisplay.name = (0, _utils.getHostNameFromUrl)(metadata.issuer.id);
  }
  return {
    ...issuerDisplay,
    name: issuerDisplay.name ?? 'Unknown'
  };
}
function getW3cIssuerDisplay(credential, openId4VcMetadata) {
  const issuerDisplay = getIssuerDisplay(openId4VcMetadata);

  // If openid metadata is not available, try to extract display metadata from the credential based on JFF metadata
  const jffCredential = credential;
  const issuerJson = typeof jffCredential.issuer === 'string' ? undefined : jffCredential.issuer;

  // Issuer Display from JFF
  if (!issuerDisplay.logo || !issuerDisplay.logo.url) {
    issuerDisplay.logo = issuerJson !== null && issuerJson !== void 0 && issuerJson.logoUrl ? {
      url: issuerJson === null || issuerJson === void 0 ? void 0 : issuerJson.logoUrl
    } : issuerJson !== null && issuerJson !== void 0 && issuerJson.image ? {
      url: typeof issuerJson.image === 'string' ? issuerJson.image : issuerJson.image.id
    } : undefined;
  }

  // Issuer name from JFF
  if (!issuerDisplay.name) {
    issuerDisplay.name = issuerJson === null || issuerJson === void 0 ? void 0 : issuerJson.name;
  }
  return processIssuerDisplay(openId4VcMetadata, issuerDisplay);
}
function getSdJwtIssuerDisplay(openId4VcMetadata) {
  const issuerDisplay = getIssuerDisplay(openId4VcMetadata);
  return processIssuerDisplay(openId4VcMetadata, issuerDisplay);
}
function getCredentialDisplay(credentialPayload, openId4VcMetadata) {
  const credentialDisplay = {};
  if (openId4VcMetadata) {
    const openidCredentialDisplay = findDisplay(openId4VcMetadata.credential.display);
    credentialDisplay.name = openidCredentialDisplay === null || openidCredentialDisplay === void 0 ? void 0 : openidCredentialDisplay.name;
    credentialDisplay.description = openidCredentialDisplay === null || openidCredentialDisplay === void 0 ? void 0 : openidCredentialDisplay.description;
    credentialDisplay.textColor = openidCredentialDisplay === null || openidCredentialDisplay === void 0 ? void 0 : openidCredentialDisplay.text_color;
    credentialDisplay.backgroundColor = openidCredentialDisplay === null || openidCredentialDisplay === void 0 ? void 0 : openidCredentialDisplay.background_color;
    credentialDisplay.backgroundImage = openidCredentialDisplay !== null && openidCredentialDisplay !== void 0 && openidCredentialDisplay.background_image ? {
      url: openidCredentialDisplay.background_image.url,
      altText: openidCredentialDisplay.background_image.alt_text
    } : undefined;
  }
  return credentialDisplay;
}
function getW3cCredentialDisplay(credential, openId4VcMetadata) {
  var _jffCredential$creden;
  const credentialDisplay = getCredentialDisplay(credential, openId4VcMetadata);

  // If openid metadata is not available, try to extract display metadata from the credential based on JFF metadata
  const jffCredential = credential;
  if (!credentialDisplay.name) {
    credentialDisplay.name = jffCredential.name;
  }

  // If there's no name for the credential, we extract it from the last type
  // and sanitize it. This is not optimal. But provides at least something.
  if (!credentialDisplay.name && jffCredential.type.length > 1) {
    const lastType = jffCredential.type[jffCredential.type.length - 1];
    credentialDisplay.name = lastType && !lastType.startsWith('http') ? (0, _utils.sanitizeString)(lastType) : undefined;
  }

  // Use background color from the JFF credential if not provided by the OID4VCI metadata
  if (!credentialDisplay.backgroundColor && (_jffCredential$creden = jffCredential.credentialBranding) !== null && _jffCredential$creden !== void 0 && _jffCredential$creden.backgroundColor) {
    credentialDisplay.backgroundColor = jffCredential.credentialBranding.backgroundColor;
  }
  return {
    ...credentialDisplay,
    // Last fallback, if there's really no name for the credential, we use a generic name
    name: credentialDisplay.name ?? 'Credential'
  };
}
function getSdJwtCredentialDisplay(credentialPayload, openId4VcMetadata) {
  const credentialDisplay = getCredentialDisplay(credentialPayload, openId4VcMetadata);
  if (!credentialDisplay.name && typeof credentialPayload.vct === 'string') {
    credentialDisplay.name = (0, _utils.sanitizeString)(credentialPayload.vct);
  }
  return {
    ...credentialDisplay,
    name: credentialDisplay.name ?? 'Credential'
  };
}
function filterAndMapSdJwtKeys(sdJwtVcPayload) {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const {
    _sd_alg,
    _sd_hash,
    iss,
    vct,
    cnf,
    iat,
    exp,
    nbf,
    ...visibleProperties
  } = sdJwtVcPayload;
  const credentialMetadata = {
    type: vct,
    issuer: iss,
    holder: cnf
  };
  if (iat) {
    credentialMetadata.issuedAt = new Date(iat * 1000);
  }
  if (exp) {
    credentialMetadata.validUntil = new Date(exp * 1000);
  }
  if (nbf) {
    credentialMetadata.validFrom = new Date(nbf * 1000);
  }
  return {
    visibleProperties,
    metadata: credentialMetadata
  };
}
function getCredentialForDisplaySdJwt(credentialRecord, metadata) {
  const {
    disclosures,
    jwt
  } = (0, _decode.decodeSdJwtSync)(credentialRecord.compactSdJwtVc, (data, alg) => _core.Hasher.hash(data, alg));
  const decodedPayload = (0, _decode.getClaimsSync)(jwt.payload, disclosures, (data, alg) => _core.Hasher.hash(data, alg));
  const issuerDisplay = getSdJwtIssuerDisplay(metadata);
  const credentialDisplay = getSdJwtCredentialDisplay(decodedPayload, metadata);
  return {
    id: `sd-jwt-vc-${credentialRecord.id}`,
    createdAt: credentialRecord.createdAt,
    display: {
      ...credentialDisplay,
      issuer: issuerDisplay
    },
    attributes: filterAndMapSdJwtKeys(decodedPayload).visibleProperties
  };
}
function getCredentialForDisplay(credentialRecord) {
  const openId4VcMetadata = (0, _metadata.getOpenId4VcCredentialMetadata)(credentialRecord);
  if (credentialRecord instanceof _core.SdJwtVcRecord) {
    return getCredentialForDisplaySdJwt(credentialRecord, openId4VcMetadata);
  }
  const credential = _core.JsonTransformer.toJSON(credentialRecord.credential.claimFormat === _core.ClaimFormat.JwtVc ? credentialRecord.credential.credential : credentialRecord.credential);
  const issuerDisplay = getW3cIssuerDisplay(credential, openId4VcMetadata);
  const credentialDisplay = getW3cCredentialDisplay(credential, openId4VcMetadata);

  // to be implimented later support credential with multiple subjects
  const credentialAttributes = Array.isArray(credential.credentialSubject) ? credential.credentialSubject[0] ?? {} : credential.credentialSubject;
  return {
    id: `w3c-credential-${credentialRecord.id}`,
    createdAt: credentialRecord.createdAt,
    display: {
      ...credentialDisplay,
      issuer: issuerDisplay
    },
    credential,
    attributes: credentialAttributes
  };
}
//# sourceMappingURL=display.js.map