const { Builder, By } = require('selenium-webdriver'),
  chrome = require('selenium-webdriver/chrome.js'),
  chromeOptions = new chrome.Options(),
  { readFile, readdir } = require('node:fs/promises');

chromeOptions.addArguments('--headless', '--disable-gpu', '--no-sandbox');

const buildPath = 'build/assets/images';
const defaultScenario = 'scenario-side_show';
const fixtureFilePath = './test/integration/fixtures/scenario.svg';

let driver, fixture, scenario;

beforeAll(async () => {
  const dirread = readdir(buildPath);
  const fileRead = readFile(fixtureFilePath, 'utf8');
  const filenames = await dirread;
  scenario = filenames.find(filename => filename.includes(defaultScenario));
  fixture = await fileRead;
});

beforeEach(async () => {
  driver = new Builder().forBrowser('chrome').setChromeOptions(chromeOptions).build();
});

describe('a trooper', () => {
  beforeEach(async () => {
    await mockResponse(driver, `/assets/images/${scenario}`, fixture, (document) => {
      placeCounter(document, createTroopCounter(), { q: 0, r: 0, s: 0 });
      return svgDocument(document);
    });
  });

  it('is selected when its counter is clicked', async () => {
    await driver.get(url('/'));
    await page.waitUntilMapLoaded(driver);

    const record = page.findTroopRecordEl(driver);
    const mapResource = page.findMapResourceEl(driver);

    await page.expectNotSelected(await record);
    const counter = await page.findElInFrame(await mapResource, By.css(page.troopCounterSelector()));
    await page.expectNotSelected(counter);

    await counter.click();
    await takeScreenshot(driver);
    await page.expectSelected(counter);
    await driver.switchTo().defaultContent();
    await page.expectSelected(await record);
  });

  it('is selected when its record is clicked', async () => {
    await driver.get(url('/'));
    await page.waitUntilMapLoaded(driver);

    const record = page.findTroopRecordEl(driver);
    const mapResource = page.findMapResourceEl(driver);

    await page.expectNotSelected(await record);
    const counter = await page.findElInFrame(await mapResource, By.css(page.troopCounterSelector()));
    await page.expectNotSelected(counter);

    await driver.switchTo().defaultContent();
    await record.click();

    await page.expectSelected(await record);
    await driver.switchTo().frame(await mapResource);
    await page.expectSelected(counter);
  });

  it.todo('is selected when its off-board counter is clicked');
});

describe('a selected trooper', () => {
  beforeEach(async () => {
    await mockResponse(driver, `/assets/images/${scenario}`, fixture, (document) => {
      placeCounter(document, selectCounter(createTroopCounter()), { x: 1, y: 1 });
      return svgDocument(document);
    });
  });

  it('is deselected when its counter is clicked', async () => {
    await driver.get(url('/'));
    await page.waitUntilMapLoaded(driver);

    const record = page.findTroopRecordEl(driver);
    const mapResource = page.findMapResourceEl(driver);

    await page.expectSelected(await record);
    const counter = await page.findElInFrame(await mapResource, By.css(page.troopCounterSelector()));
    await page.expectSelected(counter);

    await counter.click();

    await page.expectNotSelected(counter);
    await driver.switchTo().defaultContent();
    await page.expectNotSelected(await record);
  });

  it('is deselected when its record is clicked', async () => {
    await driver.get(url('/'));
    await page.waitUntilMapLoaded(driver);

    const record = page.findTroopRecordEl(driver);
    const mapResource = page.findMapResourceEl(driver);

    await page.expectSelected(await record);
    const counter = await page.findElInFrame(await mapResource, By.css(page.troopCounterSelector()));
    await page.expectSelected(counter);

    await driver.switchTo().defaultContent();
    await record.click();

    await page.expectNotSelected(await record);
    await driver.switchTo().frame(await mapResource);
    await page.expectNotSelected(counter);
  });

  it.todo('is deselected when another trooper is selected');
});

afterEach(async () => {
  await driver.quit();
});
