import {join, dirname} from "node:path";
import {test, expect} from "@jest/globals";

import * as rollup from "rollup";
import {debugPrintOutput, getCode} from "../util/index.ts";
import {resolve} from "node:path";
import {writeFile} from "node:fs/promises";

import html from "../../src/index.ts";

const output = {
  dir: 'output', // Output all files
  format: 'es', //  iifi and cjs should be added to tests
  sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
  // Prevent hashes from being added (and screw up the snapshots)
  chunkFileNames: '[name].js',
  entryFileNames: '[name].[extname]',
  assetFileNames: '[name].[extname]',
};

import {fileURLToPath} from "node:url";
import {pathToFileURL} from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));
process.chdir(join(__dirname, 'fixtures'));


test('watch', async () => {
  const origContent = `
    export const a = 1; // DO NOT CHANGE ME HERE, but in ../test.js
  `;
  const changeContent = `
    export const a = 2; // If i show up as a changed file, then the watch test has gone wrong!
  `

  const path =  resolve(__dirname, 'fixtures/watched-file.js');
  await writeFile(path, origContent, {encoding: 'utf-8'});

  const watcher = rollup.watch({
    input: 'index.html',
    output,
    plugins: [
      html({
      }),
    ],
    watch: {
      skipWrite: true,
    }
  });

  const steps = [
    async (bundle)=>{
      await writeFile(path, changeContent, {encoding: 'utf-8'});
      // Just wait on the watch mode to pick up on the changes
    },
    async (bundle)=>{
      const code = await getCode(bundle, output);
      debugPrintOutput('watch',code);

      // Reset the source file
      await writeFile(path, origContent, {encoding: 'utf-8'});

      // Assert the output is what we exapect;
      expect(code).toMatchSnapshot();

      watcher
    },
  ];
  const log = console.log;

  await new Promise((resolve, reject)=>{
    watcher.on('event', async (event) => {
      const {result} = event;
      switch (event.code) {
        case "START":
          log(`WATCH STARTED`);
          break;
        case "BUNDLE_START":
          log(`REBUILDING...`);

          break;
        case "BUNDLE_END":
          log(`Rebuilt...`);
          const cb = steps.shift();

          const generated = await result.generate(output);
          const cbResult = await cb(result);
          if(steps.length===0){
            watcher.close();
            resolve();
          }

          break;
        case "ERROR":
          reject(event.error);
          break;
      }
      if (result) {
        result.close();
      }
    });
  });

  await watcher.close();
});
