/**
 * @license
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed 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.
 */
import {GrAnnotationActionsContext} from './gr-annotation-actions-context';
import {GrDiffLine} from '../../diff/gr-diff/gr-diff-line';
import {
  CoverageRange,
  DiffLayer,
  DiffLayerListener,
} from '../../../types/types';
import {Side} from '../../../constants/constants';
import {PluginApi} from '../../plugins/gr-plugin-types';
import {ChangeInfo, NumericChangeId} from '../../../types/common';

type AddLayerFunc = (ctx: GrAnnotationActionsContext) => void;

type NotifyFunc = (
  path: string,
  start: number,
  end: number,
  side: Side
) => void;

export type CoverageProvider = (
  changeNum: NumericChangeId,
  path: string,
  basePatchNum?: number,
  patchNum?: number,
  change?: ChangeInfo
) => Promise<Array<CoverageRange>>;

export class GrAnnotationActionsInterface {
  // Collect all annotation layers instantiated by getLayer. Will be used when
  // notifying their listeners in the notify function.
  private annotationLayers: AnnotationLayer[] = [];

  private coverageProvider: CoverageProvider | null = null;

  // Default impl is a no-op.
  private addLayerFunc: AddLayerFunc = () => {};

  constructor(private readonly plugin: PluginApi) {
    // Return this instance when there is an annotatediff event.
    plugin.on('annotatediff', this);
  }

  /**
   * Register a function to call to apply annotations. Plugins should use
   * GrAnnotationActionsContext.annotateRange and
   * GrAnnotationActionsContext.annotateLineNumber to apply a CSS class to the
   * line content or the line number.
   *
   * @param addLayerFunc The function
   * that will be called when the AnnotationLayer is ready to annotate.
   */
  addLayer(addLayerFunc: AddLayerFunc) {
    this.addLayerFunc = addLayerFunc;
    return this;
  }

  /**
   * The specified function will be called with a notify function for the plugin
   * to call when it has all required data for annotation. Optional.
   *
   * @param notifyFunc See doc of the notify function below to see what it does.
   */
  addNotifier(notifyFunc: (n: NotifyFunc) => void) {
    notifyFunc(
      (path: string, startRange: number, endRange: number, side: Side) =>
        this.notify(path, startRange, endRange, side)
    );
    return this;
  }

  /**
   * The specified function will be called when a gr-diff component is built,
   * and feeds the returned coverage data into the diff. Optional.
   *
   * Be sure to call this only once and only from one plugin. Multiple coverage
   * providers are not supported. A second call will just overwrite the
   * provider of the first call.
   */
  setCoverageProvider(
    coverageProvider: CoverageProvider
  ): GrAnnotationActionsInterface {
    if (this.coverageProvider) {
      console.warn('Overwriting an existing coverage provider.');
    }
    this.coverageProvider = coverageProvider;
    return this;
  }

  /**
   * Used by Gerrit to look up the coverage provider. Not intended to be called
   * by plugins.
   */
  getCoverageProvider() {
    return this.coverageProvider;
  }

  /**
   * Returns a checkbox HTMLElement that can be used to toggle annotations
   * on/off. The checkbox will be initially disabled. Plugins should enable it
   * when data is ready and should add a click handler to toggle CSS on/off.
   *
   * Note1: Calling this method from multiple plugins will only work for the
   * 1st call. It will print an error message for all subsequent calls
   * and will not invoke their onAttached functions.
   * Note2: This method will be deprecated and eventually removed when
   * https://bugs.chromium.org/p/gerrit/issues/detail?id=8077 is
   * implemented.
   *
   * @param checkboxLabel Will be used as the label for the checkbox.
   * Optional. "Enable" is used if this is not specified.
   * @param onAttached The function that will be called
   * when the checkbox is attached to the page.
   */
  enableToggleCheckbox(
    checkboxLabel: string,
    onAttached: (checkboxEl: Element | null) => void
  ) {
    this.plugin.hook('annotation-toggler').onAttached(element => {
      if (!element.content) {
        console.error('plugin endpoint without content.');
        return;
      }
      if (!element.content.hidden) {
        console.error(
          element.content.id + ' is already enabled. Cannot re-enable.'
        );
        return;
      }
      element.content.removeAttribute('hidden');

      const label = element.content.querySelector('#annotation-label');
      if (label) {
        if (checkboxLabel) {
          label.textContent = checkboxLabel;
        } else {
          label.textContent = 'Enable';
        }
      }
      const checkbox = element.content.querySelector('#annotation-checkbox');
      onAttached(checkbox);
    });
    return this;
  }

  /**
   * The notify function will call the listeners of all required annotation
   * layers. Intended to be called by the plugin when all required data for
   * annotation is available.
   *
   * @param path The file path whose listeners should be notified.
   * @param start The line where the update starts.
   * @param end The line where the update ends.
   * @param side The side of the update ('left' or 'right').
   */
  notify(path: string, start: number, end: number, side: Side) {
    for (const annotationLayer of this.annotationLayers) {
      // Notify only the annotation layer that is associated with the specified
      // path.
      if (annotationLayer.path === path) {
        annotationLayer.notifyListeners(start, end, side);
      }
    }
  }

  /**
   * Should be called to register annotation layers by the framework. Not
   * intended to be called by plugins.
   *
   * Don't forget to dispose layer.
   *
   * @param path The file path (eg: /COMMIT_MSG').
   * @param changeNum The Gerrit change number.
   */
  getLayer(path: string, changeNum: number) {
    const annotationLayer = new AnnotationLayer(
      path,
      changeNum,
      this.addLayerFunc
    );
    this.annotationLayers.push(annotationLayer);
    return annotationLayer;
  }

  disposeLayer(path: string) {
    this.annotationLayers = this.annotationLayers.filter(
      annotationLayer => annotationLayer.path !== path
    );
  }
}

export class AnnotationLayer implements DiffLayer {
  private listeners: DiffLayerListener[] = [];

  /**
   * Used to create an instance of the Annotation Layer interface.
   *
   * @param path The file path (eg: /COMMIT_MSG').
   * @param changeNum The Gerrit change number.
   * @param addLayerFunc The function
   * that will be called when the AnnotationLayer is ready to annotate.
   */
  constructor(
    readonly path: string,
    private readonly changeNum: number,
    private readonly addLayerFunc: AddLayerFunc
  ) {
    this.listeners = [];
  }

  /**
   * Register a listener for layer updates.
   * Don't forget to removeListener when you stop using layer.
   *
   * @param fn The update handler function.
   * Should accept as arguments the line numbers for the start and end of
   * the update and the side as a string.
   */
  addListener(listener: DiffLayerListener) {
    this.listeners.push(listener);
  }

  removeListener(listener: DiffLayerListener) {
    this.listeners = this.listeners.filter(f => f !== listener);
  }

  /**
   * Layer method to add annotations to a line.
   *
   * @param contentEl The DIV.contentText element of the line
   * content to apply the annotation to using annotateRange.
   * @param lineNumberEl The TD element of the line number to
   * apply the annotation to using annotateLineNumber.
   * @param line The line object.
   */
  annotate(
    contentEl: HTMLElement,
    lineNumberEl: HTMLElement,
    line: GrDiffLine
  ) {
    const annotationActionsContext = new GrAnnotationActionsContext(
      contentEl,
      lineNumberEl,
      line,
      this.path,
      this.changeNum
    );
    this.addLayerFunc(annotationActionsContext);
  }

  /**
   * Notify Layer listeners of changes to annotations.
   *
   * @param start The line where the update starts.
   * @param end The line where the update ends.
   * @param side The side of the update. ('left' or 'right')
   */
  notifyListeners(start: number, end: number, side: Side) {
    for (const listener of this.listeners) {
      listener(start, end, side);
    }
  }
}
