import * as fs from 'fs';
import * as path from 'path';
import puppeteer, { Browser } from 'puppeteer';
import { CHROME_EXECUTABLE_PATH } from './chrome_downloader/chrome_executable_path';

// File inside $ENV_DIR containing the demo page server's TCP port. Only applies to Bazel tests
// using the test_on_env rule.
const ENV_PORT_FILE_BASE_NAME = 'port';

/** A DOM event name. */
export type EventName = string;

/**
 * Type of the function returned by addEventListenersToPuppeteerPage.
 *
 * It returns a promise that resolves when an event e of the given name is
 * caught, and returns e.detail (assumed to be of type T).
 *
 * The generic type variable T is analogous to T in e.g. CustomEvent<T>.
 *
 * Note: this works for standard DOM events as well, not just custom events.
 */
export type EventPromiseFactory = <T>(eventName: EventName) => Promise<T>;

/**
 * This function allows tests to catch document-level events in a Puppeteer
 * page.
 *
 * It takes a Puppeteer page and a list of event names, and adds event listeners
 * to the page's document for the given events. It must be called before the
 * page is loaded with e.g. page.goto() for it to work.
 *
 * The returned function takes an event name in eventNames and returns a promise
 * that will resolve to the corresponding Event object's "detail" field when the
 * event is caught. Multiple promises for the same event will be resolved in the
 * order that they were created, i.e. one caught event resolves the oldest
 * pending promise.
 */
export const addEventListenersToPuppeteerPage = async (
  page: puppeteer.Page,
  eventNames: EventName[]
) => {
  // Maps event names to FIFO queues of promise resolver functions.
  const resolverFnQueues = new Map<EventName, Function[]>();
  eventNames.forEach((eventName) => resolverFnQueues.set(eventName, []));

  // Use an unlikely prefix to reduce chances of name collision.
  await page.exposeFunction(
    '__pptr_onEvent',
    (eventName: EventName, eventDetail: any) => {
      const resolverFn = resolverFnQueues.get(eventName)!.shift(); // Dequeue.
      if (resolverFn) {
        // Undefined if queue length was 0.
        resolverFn(eventDetail);
      }
    }
  );

  // This function will be executed inside the Puppeteer page for each of the
  // events we want to listen for. It adds an event listener that will call the
  // function we've exposed in the previous step.
  const addEventListener = (name: EventName) => {
    document.addEventListener(name, (event: Event) => {
      (window as any).__pptr_onEvent(name, (event as any).detail);
    });
  };

  // Add an event listener for each one of the given events.
  const promises = eventNames.map((name) =>
    page.evaluateOnNewDocument(addEventListener, name)
  );
  await Promise.all(promises);

  // The returned function takes an event name and returns a promise that will
  // resolve to the event details when the event is caught.
  const eventPromiseFactory: EventPromiseFactory = (eventName: EventName) => {
    if (!resolverFnQueues.has(eventName)) {
      // Fail if the event wasn't included in eventNames.
      throw new Error(`no event listener for "${eventName}"`);
    }
    return new Promise(
      // Enqueue resolver function at the end of the queue.
      (resolve) => resolverFnQueues.get(eventName)!.push(resolve)
    );
  };

  return eventPromiseFactory;
};

/**
 * Returns the path to the Bazel runfiles directory.
 *
 * See:
 *  - https://docs.bazel.build/versions/master/skylark/rules.html#runfiles-location
 *  - https://docs.bazel.build/versions/master/test-encyclopedia.html#initial-conditions
 */
const bazelRunfilesDir = () =>
  path.join(process.env.RUNFILES_DIR!, process.env.TEST_WORKSPACE!);

/**
 * Launches a Puppeteer browser. Set showBrowser to true to see the browser as it executes tests.
 * This can be handy for debugging.
 */
export const launchBrowser = (showBrowser?: boolean): Promise<Browser> => {
  // TODO(lovisolo): Do we need this? Can't we use //puppeteer-tests:chrome for everything?
  const fontconfigSysroot = path.join(
    bazelRunfilesDir(),
    'external',
    'google_chrome'
  );
  return puppeteer.launch({
    // Use the hermetically-downloaded Chrome binary, which we get via the //puppeteer-tests:chrome
    // Bazel target, which in turn uses the @puppeteer/browsers NPM package.
    executablePath: path.join(
      bazelRunfilesDir(),
      'puppeteer-tests',
      'chrome',
      CHROME_EXECUTABLE_PATH
    ),
    // These options are required to run Puppeteer from within a Docker container, as is the case
    // under Bazel and RBE. See
    // https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker.
    //
    // Flag --no-sandbox is necessary to run Puppeteer tests under Bazel locally (i.e. not on
    // RBE) on a Swarming bot. If we do not provide said flag, we get the following error:
    //
    //     No usable sandbox! Update your kernel or see
    //     https://chromium.googlesource.com/chromium/src/+/master/docs/linux/suid_sandbox_development.md
    //     for more information on developing with the SUID sandbox. If you want to live
    //     dangerously and need an immediate workaround, you can try using --no-sandbox.
    args: ['--disable-dev-shm-usage', '--no-sandbox'],
    headless: !showBrowser,
    env: {
      ...process.env, // Headful mode breaks without this line (e.g. "unable to open X display").
      FONTCONFIG_SYSROOT: fontconfigSysroot,
    },
  });
};

/**
 * Type of the object returned by setUpPuppeteerAndDemoPageServer.
 *
 * A test suite should reuse this object in all its test cases. This object's
 * fields will be automatically updated with a fresh page and base URL before
 * each test case is executed.
 */
export interface TestBed {
  page: puppeteer.Page;
  baseUrl: string;
}

/**
 * Returns the output directory where tests should e.g. save screenshots.
 * Screenshots saved in this directory will be uploaded to Gold.
 */
export const outputDir = () => {
  // Screenshots will be saved as test undeclared outputs, which will be found at
  // at //_bazel_testlogs/path/to/my/puppeteer_test/test.outputs/outputs.zip. This is true when
  // running on RBE as well (e.g. "bazel test --config=remote").
  //
  // See the following link for more:
  // https://docs.bazel.build/versions/master/test-encyclopedia.html#test-interaction-with-the-filesystem.
  const undeclaredOutputsDir = process.env.TEST_UNDECLARED_OUTPUTS_DIR;
  if (!undeclaredOutputsDir) {
    throw new Error(
      'required environment variable TEST_UNDECLARED_OUTPUTS_DIR is unset'
    );
  }
  const outputDir = path.join(
    undeclaredOutputsDir,
    'puppeteer-test-screenshots'
  );
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir);
  }
  return outputDir;
};

/**
 * Takes a screenshot and saves it to the tests output directory to be uploaded
 * to Gold.
 *
 * The screenshot will be saved as <appName>_<testName>.png. Using the
 * application name as a prefix prevents name collisions between different apps
 * and increases consistency among test names.
 */
export function takeScreenshot(
  handle: puppeteer.Page | puppeteer.ElementHandle,
  appName: string,
  testName: string
): Promise<Buffer | string> {
  const pngPath = path.join(outputDir(), `${appName}_${testName}.png`);
  // Typescript is unhappy about the type union due to the ElementHandle having a "this"
  // typing. Both Page and ElementHandle have a screenshot method, so we can just
  // pretend it's one of those two.
  return (handle as puppeteer.Page).screenshot({ path: pngPath });
}

let browser: puppeteer.Browser;
let testBed: Partial<TestBed>;

/**
 * Once per Mocha invocation, loadCachedTestBed will launch a new Puppeteer browser window to run
 * the tests. On all subsequent calls, it will return essentially a cached handle to that
 * invocation.
 *
 * Test cases can access the demo page server's base URL and a Puppeteer page ready to be used via
 * the return value's baseUrl and page objects, respectively.
 *
 * This function assumes that each test case uses exactly one Puppeteer page (that's why it doesn't
 * expose the Browser instance to tests). The page is set up with a cookie (name: "puppeteer",
 * value: "true") to give demo pages a means to detect whether they are running within Puppeteer or
 * not.
 *
 * When debugging, it can be handy to set showBrowser to true.
 */
export async function loadCachedTestBed(showBrowser?: boolean) {
  if (testBed) {
    return testBed as TestBed;
  }
  const newTestBed: Partial<TestBed> = {};

  // Read the demo page server's TCP port.
  const envDir = process.env.ENV_DIR; // This is set by the test_on_env Bazel rule.
  if (!envDir)
    throw new Error('required environment variable ENV_DIR is unset');
  const port = parseInt(
    fs.readFileSync(path.join(envDir, ENV_PORT_FILE_BASE_NAME), 'utf8')
  );
  newTestBed.baseUrl = `http://localhost:${port}`;

  if (typeof showBrowser === 'undefined') {
    // The sk_element_puppeteer_test Bazel rule sets this environment variable to "true" for
    // "<name>_debug_headful" targets.
    showBrowser = !!process.env.PUPPETEER_TEST_SHOW_BROWSER;
  }

  browser = await launchBrowser(showBrowser);
  testBed = newTestBed;
  setBeforeAfterHooks();
  return testBed as TestBed;
}

// This sets up some handy helpers to load a new page and shut it down w/o having to expose
// the puppeteer.Browser object to the callers.
function setBeforeAfterHooks() {
  beforeEach(async () => {
    testBed.page = await browser.newPage(); // Make page available to tests.

    // Tell demo pages this is a Puppeteer test. Demo pages should not fake RPC
    // latency, render animations or exhibit any other non-deterministic
    // behavior that could result in differences in the screenshots uploaded to
    // Gold.
    await testBed.page.setCookie({
      url: testBed.baseUrl,
      name: 'puppeteer',
      value: 'true',
    });
  });

  afterEach(async () => {
    await testBed.page!.close();
  });

  // Shut down Puppeteer, otherwise tests will run forever, eventually timing out and failing.
  after(async () => {
    await browser.close();
  });
}
