/**
 * @licstart The following is the entire license notice for the
 * Javascript code in this page
 *
 * Copyright 2020 Mozilla Foundation
 *
 * Licensed 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.
 *
 * @licend The above is the entire license notice for the
 * Javascript code in this page
 */
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.writeDict = writeDict;
exports.incrementalUpdate = incrementalUpdate;

var _util = require("../shared/util.js");

var _primitives = require("./primitives.js");

var _crypto = require("./crypto.js");

function writeDict(dict, buffer, transform) {
  buffer.push("<<");

  for (const key of dict.getKeys()) {
    buffer.push(` /${key} `);
    writeValue(dict.getRaw(key), buffer, transform);
  }

  buffer.push(">>");
}

function writeStream(stream, buffer, transform) {
  writeDict(stream.dict, buffer, transform);
  buffer.push(" stream\n");
  let string = (0, _util.bytesToString)(stream.getBytes());

  if (transform !== null) {
    string = transform.encryptString(string);
  }

  buffer.push(string);
  buffer.push("\nendstream\n");
}

function writeArray(array, buffer, transform) {
  buffer.push("[");
  let first = true;

  for (const val of array) {
    if (!first) {
      buffer.push(" ");
    } else {
      first = false;
    }

    writeValue(val, buffer, transform);
  }

  buffer.push("]");
}

function numberToString(value) {
  if (Number.isInteger(value)) {
    return value.toString();
  }

  const roundedValue = Math.round(value * 100);

  if (roundedValue % 100 === 0) {
    return (roundedValue / 100).toString();
  }

  if (roundedValue % 10 === 0) {
    return value.toFixed(1);
  }

  return value.toFixed(2);
}

function writeValue(value, buffer, transform) {
  if ((0, _primitives.isName)(value)) {
    buffer.push(`/${value.name}`);
  } else if ((0, _primitives.isRef)(value)) {
    buffer.push(`${value.num} ${value.gen} R`);
  } else if (Array.isArray(value)) {
    writeArray(value, buffer, transform);
  } else if (typeof value === "string") {
    if (transform !== null) {
      value = transform.encryptString(value);
    }

    buffer.push(`(${(0, _util.escapeString)(value)})`);
  } else if (typeof value === "number") {
    buffer.push(numberToString(value));
  } else if ((0, _primitives.isDict)(value)) {
    writeDict(value, buffer, transform);
  } else if ((0, _primitives.isStream)(value)) {
    writeStream(value, buffer, transform);
  }
}

function writeInt(number, size, offset, buffer) {
  for (let i = size + offset - 1; i > offset - 1; i--) {
    buffer[i] = number & 0xff;
    number >>= 8;
  }

  return offset + size;
}

function writeString(string, offset, buffer) {
  for (let i = 0, len = string.length; i < len; i++) {
    buffer[offset + i] = string.charCodeAt(i) & 0xff;
  }
}

function computeMD5(filesize, xrefInfo) {
  const time = Math.floor(Date.now() / 1000);
  const filename = xrefInfo.filename || "";
  const md5Buffer = [time.toString(), filename, filesize.toString()];
  let md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0);

  for (const value of Object.values(xrefInfo.info)) {
    md5Buffer.push(value);
    md5BufferLen += value.length;
  }

  const array = new Uint8Array(md5BufferLen);
  let offset = 0;

  for (const str of md5Buffer) {
    writeString(str, offset, array);
    offset += str.length;
  }

  return (0, _util.bytesToString)((0, _crypto.calculateMD5)(array));
}

function incrementalUpdate(originalData, xrefInfo, newRefs) {
  const newXref = new _primitives.Dict(null);
  const refForXrefTable = xrefInfo.newRef;
  let buffer, baseOffset;
  const lastByte = originalData[originalData.length - 1];

  if (lastByte === 0x0a || lastByte === 0x0d) {
    buffer = [];
    baseOffset = originalData.length;
  } else {
    buffer = ["\n"];
    baseOffset = originalData.length + 1;
  }

  newXref.set("Size", refForXrefTable.num + 1);
  newXref.set("Prev", xrefInfo.startXRef);
  newXref.set("Type", _primitives.Name.get("XRef"));

  if (xrefInfo.rootRef !== null) {
    newXref.set("Root", xrefInfo.rootRef);
  }

  if (xrefInfo.infoRef !== null) {
    newXref.set("Info", xrefInfo.infoRef);
  }

  if (xrefInfo.encrypt !== null) {
    newXref.set("Encrypt", xrefInfo.encrypt);
  }

  newRefs.push({
    ref: refForXrefTable,
    data: ""
  });
  newRefs = newRefs.sort((a, b) => {
    return a.ref.num - b.ref.num;
  });
  const xrefTableData = [[0, 1, 0xffff]];
  const indexes = [0, 1];
  let maxOffset = 0;

  for (const {
    ref,
    data
  } of newRefs) {
    maxOffset = Math.max(maxOffset, baseOffset);
    xrefTableData.push([1, baseOffset, Math.min(ref.gen, 0xffff)]);
    baseOffset += data.length;
    indexes.push(ref.num);
    indexes.push(1);
    buffer.push(data);
  }

  newXref.set("Index", indexes);

  if (xrefInfo.fileIds.length !== 0) {
    const md5 = computeMD5(baseOffset, xrefInfo);
    newXref.set("ID", [xrefInfo.fileIds[0], md5]);
  }

  const offsetSize = Math.ceil(Math.log2(maxOffset) / 8);
  const sizes = [1, offsetSize, 2];
  const structSize = sizes[0] + sizes[1] + sizes[2];
  const tableLength = structSize * xrefTableData.length;
  newXref.set("W", sizes);
  newXref.set("Length", tableLength);
  buffer.push(`${refForXrefTable.num} ${refForXrefTable.gen} obj\n`);
  writeDict(newXref, buffer, null);
  buffer.push(" stream\n");
  const bufferLen = buffer.reduce((a, str) => a + str.length, 0);
  const footer = `\nendstream\nendobj\nstartxref\n${baseOffset}\n%%EOF\n`;
  const array = new Uint8Array(originalData.length + bufferLen + tableLength + footer.length);
  array.set(originalData);
  let offset = originalData.length;

  for (const str of buffer) {
    writeString(str, offset, array);
    offset += str.length;
  }

  for (const [type, objOffset, gen] of xrefTableData) {
    offset = writeInt(type, sizes[0], offset, array);
    offset = writeInt(objOffset, sizes[1], offset, array);
    offset = writeInt(gen, sizes[2], offset, array);
  }

  writeString(footer, offset, array);
  return array;
}