import { dirname, resolve, relative } from "path";
import { parseDocument, stringify } from "yaml";

const [, script, name, host] = process.argv;

const sopsFilePath = resolve(dirname(script), "../.sops.yaml");
const sopsFile = await Bun.file(sopsFilePath).text();
const sopsConfig = parseDocument(sopsFile);

//
// STEP 1: Get the remote key, convert to age key
//

const remoteKeyProc = Bun.spawn(`ssh-keyscan -qt ed25519 ${host}`.split(" "), {
  stderr: null,
});

const sshToAgeProc = Bun.spawn(["ssh-to-age"], {
  stdin: await new Response(remoteKeyProc.stdout).arrayBuffer(),
});

const ageKey = (await new Response(sshToAgeProc.stdout).text()).trim();

//
// STEP 2: Add to keys
//
const keysNode = sopsConfig.get("keys");
let keys = keysNode.items;

// remove keynode if it exists
keys = keys.filter((i) => i.anchor !== `m_${name}`);

// create the new key node
const newNode = sopsConfig.createNode(ageKey);
newNode.anchor = `m_${name}`;

keys = [...keys, newNode];

keysNode.items = keys;
sopsConfig.set("keys", keysNode);

//
// STEP 3: Add machine to creation_rules
//
const pathRegex = `secrets/${name}/[^/]+\\.(yaml|json|env|ini)$`;
const opsAnchors = keys
  .filter((i) => i.anchor.startsWith("op_"))
  .map((i) => sopsConfig.createAlias(i));

//console.log({opsAnchors})

const creationRuleTemplate = {
  path_regex: pathRegex,
  key_groups: [
    {
      age: [...opsAnchors, sopsConfig.createAlias(newNode)],
    },
  ],
};

// Remove old creation_rules entry
const creationRules = sopsConfig
  .get("creation_rules")
  .items.filter((i) => i.get("path_regex") !== pathRegex);

const creationRulesNode = sopsConfig.createNode(creationRules);
creationRulesNode.add(creationRuleTemplate);
sopsConfig.set("creation_rules", creationRulesNode);

await Bun.write(sopsFilePath, sopsConfig.toString());

console.log(
  `Finished. Added ${name} with key ${ageKey} to ${relative(
    dirname(script),
    sopsFilePath
  )}.`
);
