import path from 'path';
import fs from 'fs';
import { esbuildPlugin } from '@web/dev-server-esbuild';
import { defaultReporter, summaryReporter } from '@web/test-runner';
import { resultDbReporter } from './resultdb-reporter.mjs';
import { visualRegressionPlugin } from '@web/test-runner-visual-regression/plugin';
import pixelmatch from 'pixelmatch';
import { PNG } from 'pngjs';
import { playwrightLauncher } from '@web/test-runner-playwright';

const runUnderBazel = !!process.env['RUNFILES_DIR'];
// We set this to a non-zero value because of sub-pixel rendering noise that
// can create false positives.
const diffThreshold = .02;

function testRunnerHtmlFactory(prefix) {
  return (testFramework) => `
    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" href="${prefix}app/styles/main.css">
        <link rel="stylesheet" href="${prefix}app/styles/fonts.css">
        <link rel="stylesheet" href="${prefix}app/styles/material-icons.css">
      </head>
      <body>
        <script type="module" src="${testFramework}"></script>
      </body>
    </html>
  `;
}

function getModulesDir() {
  if (!runUnderBazel) {
    return [
      path.join(process.cwd(), 'plugins/node_modules'),
      path.join(process.cwd(), 'app/node_modules'),
      path.join(process.cwd(), 'node_modules'),
    ];
  }

  const cwd = process.cwd();
  return [
    path.join(cwd, 'plugins/node_modules'),
    path.join(cwd, 'polygerrit-ui/node_modules'),
    path.join(cwd, 'polygerrit-ui/app/node_modules'),
  ];
}

function getArgValue(flag) {
  const withEquals = process.argv.find((arg) => arg.startsWith(`${flag}=`));
  if (withEquals) return withEquals.split('=')[1];

  const index = process.argv.indexOf(flag);
  if (index !== -1 && process.argv[index + 1] && !process.argv[index + 1].startsWith('--')) {
    return process.argv[index + 1];
  }

  return undefined;
}

const pathPrefix = runUnderBazel ? 'polygerrit-ui/' : '';
const testFiles = getArgValue('--test-files');
const runScreenshots = process.argv.includes('--run-screenshots');
const rootDir = getArgValue('--root-dir') ?? `${path.resolve(process.cwd())}/`;
const tsConfig = getArgValue('--ts-config') ?? `${pathPrefix}app/tsconfig.json`;

// When running screenshots, we serve from the root directory, so we need to
// prepend polygerrit-ui/ to the path.
// When running under Bazel, we also need strictly fully qualified paths.
const stylePathPrefix = 'polygerrit-ui/';

const chromeExecutablePath = [
  process.env['CHROME_BIN'],
  process.env['CI_CHROME_BIN'],
  '/usr/bin/google-chrome',
].find(p => p && fs.existsSync(p));

/** @type {import('@web/test-runner').TestRunnerConfig} */
const config = {
  // Default is CPU cores / 2. Use default
  ...(runUnderBazel ? { concurrency: 1 } : {}),
  // WORKAROUND: Prevents tests from failing or timing out when run concurrently.
  // Recent Chrome versions aggressively throttle inactive tabs, which interferes with
  // parallel tests. These flags disable that behavior, ensuring tests that rely on
  // visibility or timers run reliably.
  // Some details: https://g-issues.gerritcodereview.com/issues/365565157
  browsers: [
    playwrightLauncher({
      product: 'chromium',
      launchOptions: {
        ...(chromeExecutablePath ? { executablePath: chromeExecutablePath } : {}),
        args: [
          '--no-sandbox',
          '--disable-dev-shm-usage',
          '--disable-background-timer-throttling',
          '--disable-backgrounding-occluded-windows',
          '--disable-renderer-backgrounding',
          '--font-render-hinting=none',
          '--disable-font-subpixel-rendering',
          '--disable-lcd-text',
        ],
      },
    }),
  ],

  files: runScreenshots
    ? [
      // If --run-screenshots is set, ONLY run screenshot tests.
      testFiles ?? `${pathPrefix}app/**/*_screenshot_test.{ts,js}`,
      `!${pathPrefix}**/node_modules/**/*`,
    ]
    : [
      // Otherwise, run all tests EXCEPT screenshot tests
      testFiles ?? `${pathPrefix}app/**/*_test.{ts,js}`,
      `!${pathPrefix}**/node_modules/**/*`,
      `!${pathPrefix}app/**/*_screenshot_test.{ts,js}`,
    ],

  port: 9876,

  nodeResolve: {
    modulePaths: getModulesDir(),
    dedupe: [
      'lit',
      'lit-html',
      'lit-element',
      '@open-wc/testing',
      '@open-wc/testing-helpers',
      'sinon',
    ],
  },

  testFramework: {
    config: {
      ui: 'tdd',
      timeout: runScreenshots ? 10000 : 2000,
    },
  },

  coverageConfig: {
    report: true,
    reportDir: 'coverage',
    reporters: ['lcov', 'text'],
  },

  plugins: [
    esbuildPlugin({
      ts: true,
      target: 'es2020',
      tsconfig: tsConfig,
    }),
    visualRegressionPlugin({
      baseDir: pathPrefix ? `${pathPrefix}screenshots` : 'screenshots',
      // TODO(milutin): Tweak these values - diffOptions threshold is for color change
      // and failureThreshold is for pixel change. We need to find a balance to allow
      // CI to pass, but also catch regressions.
      diffOptions: { threshold: 0.6 },
      failureThreshold: diffThreshold,
      failureThresholdType: 'percent',
      update: process.argv.includes('--update-screenshots'),
      // The visual regression plugin by default blindly overwrites all goldens
      // when the --update-screenshots flag is used. This modifies file timestamps
      // and pollutes version control with identical images or sub-threshold
      // aliasing diffs. We intercept the saveBaseline hook to diff the image in
      // memory and only save it if the visual diff exceeds our 2% threshold.
      saveBaseline: async ({ filePath, content }) => {
        let oldContent;
        try {
          oldContent = await fs.promises.readFile(filePath);
        } catch (e) {
          // file doesn't exist
        }

        if (oldContent) {
          if (content.equals(oldContent)) {
            return;
          }

          let basePng;
          let newPng;
          try {
            basePng = PNG.sync.read(oldContent);
            newPng = PNG.sync.read(content);
          } catch (e) {
            console.warn('Failed to parse PNGs for diff checking', e);
          }

          if (basePng && newPng && basePng.width === newPng.width && basePng.height === newPng.height) {
            const numDiffPixels = pixelmatch(
              basePng.data,
              newPng.data,
              null,
              basePng.width,
              basePng.height,
              { threshold: 0.6 }
            );

            const diffPercentage = (numDiffPixels / (basePng.width * basePng.height)) * 100;
            if (diffPercentage <= diffThreshold) {
              return;
            }
          }
        }

        await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
        await fs.promises.writeFile(filePath, content);
      },
    }),
  ],

  // serve from gerrit root directory so that we can serve fonts from
  // /lib/fonts/ for screenshots tests, see middleware.
  rootDir: runUnderBazel ? rootDir : '..',

  reporters: [
    defaultReporter(),
    summaryReporter(),
    resultDbReporter(),
  ],

  middleware: [
    // Fonts are in /lib/fonts/, but css tries to load from
    // /polygerrit-ui/app/fonts/. In production this works because our build
    // copies them over, see /polygerrit-ui/BUILD
    async (context, next) => {
      if (context.url.startsWith('/polygerrit-ui/app/fonts/')) {
        context.url = context.url.replace('/polygerrit-ui/app/', '/lib/');
      }
      await next();
    },
  ],

  testRunnerHtml: testRunnerHtmlFactory(stylePathPrefix),
};

export default config;
