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');
// Under Bazel, module imports may resolve through runfile symlinks to
// rules_js package stores. Both the runfiles tree and those stores are under
// bazel-out/<config>/bin, so use that as the WTR root.
function getBazelBinDir() {
  const cwd = path.resolve(process.cwd()).replace(/\\/g, '/');
  const match = cwd.match(/^(.*\/bazel-out\/[^/]+\/bin)(?:\/|$)/);
  return `${match?.[1] ?? cwd}/`;
}

const rootDir = getArgValue('--root-dir') ?? getBazelBinDir();
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;
