const { ERROR } = require("./errors");

function isObject(value) {
  return value && typeof value === "object" && !Array.isArray(value);
}

function validateInput(input) {
  if (!isObject(input)) return ERROR.BAD_INPUT;
  if (typeof input.markdown !== "string") return ERROR.BAD_INPUT;
  if (!isObject(input.repoMeta)) return ERROR.BAD_INPUT;
  if (!isObject(input.config) || !isObject(input.config.pdf)) return ERROR.BAD_INPUT;
  if (typeof input.manifestSHA !== "string") return ERROR.BAD_INPUT;

  const pdf = input.config.pdf;
  if (!["strict", "relaxed"].includes(pdf.determinism)) return ERROR.BAD_CONFIG;
  if (!["commit_time", "render_time"].includes(pdf.timestamp)) return ERROR.BAD_CONFIG;
  if (!["basic", "professional"].includes(pdf.typography)) return ERROR.BAD_CONFIG;
  if (!isObject(pdf.mermaid)) return ERROR.BAD_CONFIG;
  if (!["fast", "balanced", "prestige"].includes(pdf.mermaid.strategy)) return ERROR.BAD_CONFIG;
  if (typeof pdf.mermaid.caption !== "boolean") return ERROR.BAD_CONFIG;
  if (!isObject(pdf.orphansWidows) || typeof pdf.orphansWidows.enforce !== "boolean") return ERROR.BAD_CONFIG;
  if (!isObject(pdf.footer) || typeof pdf.footer.enabled !== "boolean") return ERROR.BAD_CONFIG;

  if (pdf.determinism === "strict" && pdf.timestamp !== "commit_time") return ERROR.BAD_CONFIG;

  const rm = input.repoMeta;
  if (typeof rm.owner !== "string") return ERROR.BAD_INPUT;
  if (typeof rm.repo !== "string") return ERROR.BAD_INPUT;
  if (typeof rm.path !== "string") return ERROR.BAD_INPUT;
  if (typeof rm.commitSHA !== "string") return ERROR.BAD_INPUT;
  if (typeof rm.commitTimeRFC3339 !== "string") return ERROR.BAD_INPUT;

  return null;
}

module.exports = { validateInput };

