"use strict";

exports.__esModule = true;
exports.default = void 0;
var _pdfkit = _interopRequireDefault(require("pdfkit"));
var _variableType = require("./helpers/variableType");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const typeName = (bold, italics) => {
  let type = 'normal';
  if (bold && italics) {
    type = 'bolditalics';
  } else if (bold) {
    type = 'bold';
  } else if (italics) {
    type = 'italics';
  }
  return type;
};
class PDFDocument extends _pdfkit.default {
  constructor(fonts = {}, images = {}, patterns = {}, attachments = {}, options = {}, virtualfs = null, localAccessPolicy = undefined) {
    super(options);
    this.fonts = {};
    this.fontCache = {};
    for (let font in fonts) {
      if (fonts.hasOwnProperty(font)) {
        let fontDef = fonts[font];
        this.fonts[font] = {
          normal: fontDef.normal,
          bold: fontDef.bold,
          italics: fontDef.italics,
          bolditalics: fontDef.bolditalics
        };
      }
    }
    this.patterns = {};
    for (let pattern in patterns) {
      if (patterns.hasOwnProperty(pattern)) {
        let patternDef = patterns[pattern];
        this.patterns[pattern] = this.pattern(patternDef.boundingBox, patternDef.xStep, patternDef.yStep, patternDef.pattern, patternDef.colored);
      }
    }
    this.images = images;
    this.attachments = attachments;
    this.virtualfs = virtualfs;
    this.localAccessPolicy = localAccessPolicy;
  }
  getFontType(bold, italics) {
    return typeName(bold, italics);
  }
  getFontFile(familyName, bold, italics) {
    let type = this.getFontType(bold, italics);
    if (!this.fonts[familyName] || !this.fonts[familyName][type]) {
      return null;
    }
    return this.fonts[familyName][type];
  }
  provideFont(familyName, bold, italics) {
    let type = this.getFontType(bold, italics);
    if (this.getFontFile(familyName, bold, italics) === null) {
      throw new Error(`Font '${familyName}' in style '${type}' is not defined in the font section of the document definition.`);
    }
    this.fontCache[familyName] = this.fontCache[familyName] || {};
    if (!this.fontCache[familyName][type]) {
      let def = this.fonts[familyName][type];
      if (!Array.isArray(def)) {
        def = [def];
      }
      if (this.virtualfs && this.virtualfs.existsSync(def[0])) {
        def[0] = this.virtualfs.readFileSync(def[0]);
      } else {
        this.validateLocalFile(def[0]);
      }
      this.fontCache[familyName][type] = this.font(...def)._font;
    }
    return this.fontCache[familyName][type];
  }
  provideImage(src) {
    const realImageSrc = src => {
      let image = this.images[src];
      if (!image) {
        return src;
      }
      if (this.virtualfs && this.virtualfs.existsSync(image)) {
        return this.virtualfs.readFileSync(image);
      }
      let index = image.indexOf('base64,');
      if (index < 0) {
        return this.images[src];
      }
      return Buffer.from(image.substring(index + 7), 'base64');
    };
    if (this._imageRegistry[src]) {
      return this._imageRegistry[src];
    }
    let image;
    let imageSrc = realImageSrc(src);
    this.validateLocalFile(imageSrc);
    try {
      image = this.openImage(imageSrc);
      if (!image) {
        throw new Error('No image');
      }
    } catch (error) {
      throw new Error(`Invalid image: ${error.toString()}\nImages dictionary should contain dataURL entries (or local file paths in node.js)`, {
        cause: error
      });
    }
    image.embed(this);
    this._imageRegistry[src] = image;
    return image;
  }

  /**
   * @param {Array} color pdfmake format: [<pattern name>, <color>]
   * @returns {Array} pdfkit format: [<pattern object>, <color>]
   */
  providePattern(color) {
    if (Array.isArray(color) && color.length === 2) {
      return [this.patterns[color[0]], color[1]];
    }
    return null;
  }
  provideAttachment(src) {
    const checkRequired = obj => {
      if (!obj) {
        throw new Error('No attachment');
      }
      if (!obj.src) {
        throw new Error('The "src" key is required for attachments');
      }
      return obj;
    };
    if (typeof src === 'object') {
      return checkRequired(src);
    }
    let attachment = checkRequired(this.attachments[src]);
    if (this.virtualfs && this.virtualfs.existsSync(attachment.src)) {
      return this.virtualfs.readFileSync(attachment.src);
    }
    this.validateLocalFile(attachment.src);
    return attachment;
  }
  resolveColor(color, defaultColor) {
    color = color || defaultColor;
    if (typeof this._normalizeColor === 'function') {
      if ((0, _variableType.isString)(color) && this._normalizeColor(color) === null) {
        // color is not valid
        return defaultColor;
      }
    }
    return color;
  }
  setOpenActionAsPrint() {
    let printActionRef = this.ref({
      Type: 'Action',
      S: 'Named',
      N: 'Print'
    });
    this._root.data.OpenAction = printActionRef;
    printActionRef.end();
  }
  file(src, options = {}) {
    this.validateLocalFile(src);
    return super.file(src, options);
  }
  validateLocalFile(path) {
    if (typeof this.localAccessPolicy === 'undefined') {
      return;
    }
    if (!(0, _variableType.isString)(path)) {
      return;
    }
    if (/^data:/.test(path)) {
      return;
    }
    if (this.localAccessPolicy(path) !== true) {
      throw new Error(`Access to local file denied by resource access policy: ${path}`);
    }
  }
}
var _default = exports.default = PDFDocument;