#!/usr/bin/env node

import { promises as fs } from "fs";
import { promisify } from "util";
import glob from "glob";
import path from "path";
import os from "os";

const packageFile = async (actualPath: string): Promise<any> => {
  console.log(`Packaging: ${actualPath}`);
  const packagePath = actualPath.slice(4);
  const data = await fs.readFile(actualPath, "utf-8");
  const content = Buffer.from(data, "utf-8").toString("base64");
  const fileStats = await fs.stat(actualPath);
  const permission = parseInt((fileStats.mode & 0o777).toString(8).slice(-3), 10);
  return {
    location: packagePath,
    permission,
    encode: "base64",
    content,
  };
};

const packageFiles = async () => {
  const packagedFiles: any[] = [];
  const ignoredPatterns = [/\.gitkeep/, /Gemfile/, /Gemfile.lock/, /\.ruby-version/];

  const processDir = async (dir: string) => {
    const entries = await fs.readdir(dir, { withFileTypes: true });
    for (const entry of entries) {
      const entryPath = path.join(dir, entry.name);
      if (entry.isDirectory()) {
        await processDir(entryPath);
      } else if (entry.isFile()) {
        if (!ignoredPatterns.some((pattern) => pattern.test(entry.name))) {
          packagedFiles.push(await packageFile(entryPath));
        }
      }
    }
  };

  await processDir("./src/");
  return packagedFiles;
};

export const createZPM = async ({ name, displayName, version }: Record<string, string>) => {
  const files = await packageFiles();
  const skeleton = {
    name: displayName,
    version,
    vendor: "Center for Digital Resilience",
    license: "AGPL-v3+",
    url: `https://gitlab.com/digiresilience/link/link-stack/packages/${name}`,
    buildhost: os.hostname(),
    builddate: new Date().toISOString(),
    files
  };
  const pkg = JSON.stringify(skeleton, null, 2);

  try {
    const gs = promisify(glob);
    const files = await gs(`../../docker/zammad/addons/${name}-v*.zpm`);

    for (const file of files) {
      await fs.unlink(file);
      console.log(`${file} was deleted`);
    }
  } catch (err) {
    console.error(err);
  }
  await fs.writeFile(`../../docker/zammad/addons/${name}-v${version}.zpm`, pkg, 'utf-8');
};

const main = async () => {
  const packageJSON = JSON.parse(await fs.readFile("./package.json", "utf-8"));
  const { name, displayName, version } = packageJSON;
  console.log(`Building addon ${displayName} v${version}`);
  await createZPM({ name, displayName, version });
};

main();
