/**
 * @module modules/commit-range-sk
 * @description <h2><code>commit-range-sk</code></h2>
 *
 * Displays a link that describes a range of commits in a repo. This element
 * uses the global `window.perf.commit_range_url`, which can be set on Perf via
 * the command line.
 */
import { html } from 'lit/html.js';
import { define } from '../../../elements-sk/modules/define';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { lookupCids } from '../cid/cid';
import { MISSING_DATA_SENTINEL } from '../const/const';
import { ColumnHeader, CommitNumber } from '../json';
import '../window/window';

// Converts CommitNumbers to Git hashes.
type commitNumberToHashes = (commitNumbers: CommitNumber[]) => Promise<string[]>;

/** The default implementation for commitNumberToHashes run the commit numbers
 *  through cid lookup to get the hashes by making a request to the server.
 */
const defaultcommitNumberToHashes = async (cids: CommitNumber[]): Promise<string[]> => {
  const json = await lookupCids(cids);
  return [json.commitSlice![0].hash, json.commitSlice![1].hash];
};

export class CommitRangeSk extends ElementSk {
  private _trace: number[] = [];

  private _commitIndex: number = -1;

  private _header: (ColumnHeader | null)[] | null = null;

  private _htmlTemplate = html``;

  private _commitIds: [CommitNumber, CommitNumber] | null = null;

  private _hashes: string[] | null = null;

  private _autoload: boolean = true;

  // commitNumberToHashes can be replaced to make testing easier.
  private commitNumberToHashes: commitNumberToHashes = async (
    cids: CommitNumber[]
  ): Promise<string[]> => {
    if (this._autoload) {
      const hashes = await defaultcommitNumberToHashes(cids);
      return hashes;
    }

    return [];
  };

  constructor() {
    super(CommitRangeSk.template);
  }

  private static template = (ele: CommitRangeSk) => html`${ele.htmlTemplate}`;

  connectedCallback(): void {
    super.connectedCallback();
    this._upgradeProperty('trace');
    this._upgradeProperty('commitIndex');
    this._upgradeProperty('header');
    this._render();
  }

  reset(): void {
    this._commitIndex = -1;
    this._trace = [];
    this._header = null;
    this._htmlTemplate = html``;
    this._commitIds = null;
    this._hashes = null;
    this._render();
  }

  clear(): void {
    this._htmlTemplate = html``;
    this._render();
  }

  /** Check start and end commits and determines if delta is more than 1.
   * If so, it is a range and returns true.
   * If not, it is a single commit and returns false.
   * Returns false if no commits are set.
   * @returns boolean
   */
  isRange(): boolean | null {
    if (!this._commitIds) {
      return null;
    }
    if (this._commitIds[0] >= this._commitIds[1]) {
      return false;
    }

    if (this._commitIds[0] + 1 === this._commitIds[1]) {
      return false;
    }
    return true;
  }

  async recalcLink(): Promise<void> {
    if (window.perf.commit_range_url === '' || this._commitIndex === -1) {
      this.clear();
      return;
    }

    this._commitIds = this.setCommitIds(this._commitIndex);
    if (!this._commitIds || this._commitIds.length !== 2) {
      this.clear();
      return;
    }

    try {
      let text = `${this._commitIds[1]}`;
      // Check if there are no points between start and end.
      if (this.isRange()) {
        // Add +1 to the previous commit to only show commits after previous.
        text = `${this._commitIds[0] + 1} - ${this._commitIds[1]}`;
      }
      this.htmlTemplate = html`${text}`;

      if (!this.hashes) {
        // Run the commit numbers through cid lookup to get the hashes.
        this.hashes = await this.commitNumberToHashes(this._commitIds);
      }

      // If we have the hashes, then we can build the link.
      if (this.hashes && this.hashes.length > 1) {
        let url = window.perf.commit_range_url;
        url = url.replace('{end}', this.hashes[1]);
        if (this.isRange()) {
          url = url.replace('{begin}', this.hashes[0]);
        } else {
          // Multiple hashes found, but are sequential, so use second hash only.
          url = url.replace('{begin}..', '');
          // Use +log to ensure it is the correct placeholder.
          url = url.replace('+log', '+');
        }
        this.htmlTemplate = html`<a href="${url}" target="_blank">${text}</a>`;
        // Ensure element is connected to tooltip before dispatching event.
        if (this._connected) {
          this.dispatchEvent(
            new CustomEvent('commit-range-changed', {
              bubbles: true, // Allows parent elements to catch the event.
              composed: true, // Allows event to cross shadow DOM boundaries.
            })
          );
        }
      }
    } catch (error) {
      console.log(error);
      this.clear();
    }
  }

  /** A single trace. */
  get trace(): number[] {
    return this._trace;
  }

  set trace(val: number[]) {
    this._trace = val;
    this.recalcLink();
  }

  /** An index into trace, the location of the commit being referenced. */
  get commitIndex(): number {
    return this._commitIndex;
  }

  set commitIndex(val: number) {
    this._commitIndex = val;
    this.recalcLink();
  }

  /** The ColumnHeader of the DataFrame that contains the trace. */
  get header(): (ColumnHeader | null)[] | null {
    return this._header;
  }

  set header(val: (ColumnHeader | null)[] | null) {
    this._header = val;
    this.recalcLink();
  }

  /** The hashes of the commits. */
  get hashes(): string[] | null {
    return this._hashes;
  }

  set hashes(val: string[] | null) {
    if (val !== null && val.length > 1) {
      // Only set the hashes if there are two hashes.
      this._hashes = val;
      this.recalcLink();
    }
  }

  set htmlTemplate(val: any) {
    // If the template is the same, don't re-render.
    if (this._htmlTemplate !== val) {
      this._htmlTemplate = val;
      this._render();
    }
  }

  get htmlTemplate() {
    return this._htmlTemplate;
  }

  set autoload(val: boolean) {
    this._autoload = val;
  }

  setCommitIds(commitIndex: number): [CommitNumber, CommitNumber] | null {
    if (this._trace.length === 0 || this._header === null) {
      this.clear();
      return null;
    }
    // First the previous commit that has data.
    let prevCommit = commitIndex - 1;

    while (prevCommit > 0 && this._trace[prevCommit] === MISSING_DATA_SENTINEL) {
      prevCommit -= 1;
    }

    // If we don't find a second commit then we can't present the information.
    if (prevCommit < 0) {
      this.clear();
      return null;
    }

    const startOffset = this._header[prevCommit]?.offset ?? null;
    const endOffset = this._header[commitIndex]?.offset ?? null;
    if (startOffset === null || endOffset === null) {
      this.clear();
      return null;
    }
    return [startOffset, endOffset];
  }
}

define('commit-range-sk', CommitRangeSk);
