/**
 * SPDX-FileCopyrightText: 2016-2022 The Apache Software Foundation
 * SPDX-License-Identifier: Apache-2.0
 * @license
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* global info, module, source, target, form */

import {
  makeCreateRangeSelectorMatcher,
  createTextQuoteSelectorMatcher,
  describeTextQuote,
  createTextPositionSelectorMatcher,
  describeTextPosition,
  highlightText,
} from '@apache-annotator/dom';
import { makeRefinable } from '@apache-annotator/selector';

const EXAMPLE_SELECTORS = [
  {
    type: 'TextQuoteSelector',
    exact: 'not',
  },
  {
    type: 'RangeSelector',
    startSelector: {
      type: 'TextQuoteSelector',
      exact: 'ann',
    },
    endSelector: {
      type: 'TextQuoteSelector',
      exact: '!',
    },
  },
  {
    type: 'TextQuoteSelector',
    exact: 'annotated world',
    refinedBy: {
      type: 'TextQuoteSelector',
      exact: 'tat',
    },
  },
  {
    type: 'TextQuoteSelector',
    exact: 'To annotate, or not to annotate,',
    refinedBy: {
      type: 'RangeSelector',
      startSelector: {
        type: 'TextQuoteSelector',
        exact: 'To annotate',
        refinedBy: {
          type: 'TextQuoteSelector',
          exact: 'annotate',
        },
      },
      endSelector: {
        type: 'TextQuoteSelector',
        exact: 'not to annotate',
        refinedBy: {
          type: 'TextQuoteSelector',
          exact: ' to',
        },
      },
      refinedBy: {
        type: 'TextQuoteSelector',
        exact: 'o',
      },
    },
  },
];

let moduleState = {
  cleanupFunctions: [],
};

function cleanup() {
  let removeHighlight;
  while ((removeHighlight = moduleState.cleanupFunctions.shift())) {
    removeHighlight();
  }
  target.normalize();
  info.innerText = '';
}

const createMatcher = makeRefinable((selector) => {
  const innerCreateMatcher = {
    TextQuoteSelector: createTextQuoteSelectorMatcher,
    TextPositionSelector: createTextPositionSelectorMatcher,
    RangeSelector: makeCreateRangeSelectorMatcher(createMatcher),
  }[selector.type];

  if (!innerCreateMatcher) {
    throw new Error(`Unsupported selector type: ${selector.type}`);
  }

  return innerCreateMatcher(selector);
});

async function anchor(selector) {
  const matchAll = createMatcher(selector);
  const ranges = [];

  // First collect all matches, and only then highlight them; to avoid
  // modifying the DOM while the matcher is running.
  for await (const range of matchAll(target)) {
    ranges.push(range);
  }

  for (const range of ranges) {
    const removeHighlight = highlightText(range);
    moduleState.cleanupFunctions.push(removeHighlight);
  }

  info.innerText += JSON.stringify(selector, null, 2) + '\n\n';
}

async function onSelectionChange() {
  cleanup();
  const describeMode = form.describeMode.value;
  const selection = document.getSelection();
  for (let i = 0; i < selection.rangeCount; i++) {
    const range = selection.getRangeAt(i);
    const selector =
      describeMode === 'TextPosition'
        ? await describeTextPosition(range, source)
        : await describeTextQuote(range, source, { minimumQuoteLength: 10 });
    await anchor(selector);
  }
}

function onSelectorExampleClick(event) {
  const exampleNumber = event.target.dataset.runExample;
  if (!exampleNumber) return;
  const selector = EXAMPLE_SELECTORS[exampleNumber];
  cleanup();
  anchor(selector);
  event.preventDefault();
}

function addEventListeners() {
  document.addEventListener('selectionchange', onSelectionChange);
  form.addEventListener('change', onSelectionChange);
  document.addEventListener('click', onSelectorExampleClick);
}
addEventListeners();

function removeEventListeners() {
  document.removeEventListener('selectionchange', onSelectionChange);
  form.removeEventListener('change', onSelectionChange);
  document.removeEventListener('click', onSelectorExampleClick);
}

if (module.hot) {
  module.hot.accept();
  module.hot.dispose((data) => {
    removeEventListeners();
    data.state = moduleState;
  });
  if (module.hot.data?.state) {
    moduleState = module.hot.data.state;
  }
}
