import { merge } from "lodash";
import { ComponentPolicy } from ".";
import { mkdirSync, writeFileSync } from "fs";
import { join } from "path";
import { XMLBuilder } from "fast-xml-parser";
import { exec } from "child_process";

const Builder = (tabWidth:number = 2) => new XMLBuilder({ 
  format: true,
  ignoreAttributes: false,
  indentBy: " ".repeat(tabWidth),
  attributeNamePrefix: "@",
  attributesGroupName: "attributes",
  suppressBooleanAttributes: false,
});

const generate = (policies: ComponentPolicy[]) => {
  let componentPolicies = {};
  const jcrPrimary = { "jcr:primaryType": "nt:unstructured" };

  policies.forEach((policy: ComponentPolicy) => {
    let policyNodes = {};
    const resourceType = policy.component;
    resourceType.split("/").reverse().forEach((node, index) => {
      if (index === 0) policyNodes[node] = { attributes: jcrPrimary, ...policy.format(false) }
      else policyNodes = { [node]: { attributes: jcrPrimary, ...policyNodes } };
    });
    componentPolicies = merge({}, componentPolicies, policyNodes);
  });

  return {
    "?xml": {
      attributes: {
        version: "1.0",
        encoding: "UTF-8"
      }
    },
    "jcr:root": {
      attributes: {
        "xmlns:sling": "http://sling.apache.org/jcr/sling/1.0",
        "xmlns:cq": "http://www.day.com/jcr/cq/1.0",
        "xmlns:jcr": "http://www.jcp.org/jcr/1.0",
        "xmlns:nt": "http://www.jcp.org/jcr/nt/1.0",
        "xmlns:rep": "internal",
        "jcr:mixinTypes": "[rep:AccessControllable]",
        "jcr:primaryType": "cq:Page",
      },
      "rep:policy": "",
      ...componentPolicies
    }
  };
}

export const generatePolicies = (policies: ComponentPolicy[], outputFile:string, tabWidth:number = 2) => {
  if (!policies.length || outputFile === "") {
    throw new Error("No policies to generate, or no output file specified");
  };

  const xmlBuilder = Builder(tabWidth);
  const outputFolder = join(process.cwd(), outputFile);
  mkdirSync(outputFolder, { recursive: true });
  writeFileSync(join(outputFolder, ".content.xml"), xmlBuilder.build(generate(policies)));

  exec([
    "./node_modules/.bin/prettier",
    `--tab-width ${tabWidth}`,
    "--xmlWhitespaceSensitivity ignore",
    "--write",
    outputFolder + "/.content.xml",
  ].join(" "), (err, stdout, stderr) => {
  });
}