import { spawnSync } from 'node:child_process';
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';

import { afterEach, describe, expect, it } from 'vitest';
import { parse } from 'yaml';

const temporaryDirectories: string[] = [];
afterEach(() => temporaryDirectories.splice(0).forEach((directory) => rmSync(directory, { force: true, recursive: true })));

function fixture() {
  const root = mkdtempSync(join(tmpdir(), 'onlyoffice-multi-config-'));
  temporaryDirectories.push(root);
  const releaseRoot = join(root, 'releases');
  const configRoot = join(root, 'config');
  mkdirSync(releaseRoot);
  mkdirSync(configRoot);
  return { configRoot, releaseRoot };
}

function generate(output: string, releaseRoot: string) {
  return spawnSync(process.execPath, [resolve('scripts/generate-backend-config.mjs')], {
    cwd: process.cwd(),
    encoding: 'utf8',
    env: {
      ...process.env,
      ONLYOFFICE_PLUGIN_API_BASE_URL: 'http://localhost:30000',
      ONLYOFFICE_PLUGIN_CONFIG_OUTPUT: output,
      ONLYOFFICE_PLUGIN_PUBLIC_BASE_URL: 'http://localhost:4173/onlyoffice-plugins/',
      ONLYOFFICE_PLUGIN_RELEASE: '0.1.0-dev',
      ONLYOFFICE_RELEASE_ROOT: releaseRoot,
    },
  });
}

describe('multi-plugin backend config generator', () => {
  it('generates all definitions and scenes from the registry', () => {
    const { configRoot, releaseRoot } = fixture();
    const output = join(configRoot, 'onlyoffice-plugins.yaml');

    const result = generate(output, releaseRoot);
    const yaml = readFileSync(output, 'utf8');
    const config = parse(yaml);

    expect(result.status, result.stderr).toBe(0);
    expect(config.plugins.definitions).toMatchObject({
      'eln-template-annotator': { 'public-base-url': 'http://localhost:4173/onlyoffice-plugins', release: '0.1.0-dev' },
      'eln-template-filler': { 'public-base-url': 'http://localhost:4173/onlyoffice-plugins', release: '0.1.0-dev' },
    });
    expect(config.plugins.scenes).toMatchObject([
      {
        'biz-scene': 'eln.template.annotate',
        'disabled-plugin-guids': ['asc.{AA2EA9B6-9EC2-415F-9762-634EE8D9A95E}'],
        'plugin-codes': ['eln-template-annotator'],
      },
      {
        'biz-scene': 'eln.template.fill',
        'disabled-plugin-guids': ['asc.{AA2EA9B6-9EC2-415F-9762-634EE8D9A95E}'],
        'plugin-codes': ['eln-template-filler'],
      },
    ]);
    expect(yaml).not.toMatch(/ticket|token|fields:/i);
  });

  it('refuses to write into the public release root', () => {
    const { releaseRoot } = fixture();
    const output = join(releaseRoot, 'onlyoffice-plugins.yaml');

    const result = generate(output, releaseRoot);

    expect(result.status).toBe(1);
    expect(result.stderr).toContain('must be outside ONLYOFFICE_RELEASE_ROOT');
    expect(existsSync(output)).toBe(false);
  });
});
