/**
 * @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;
  }

  /**
   * Recalculates the link based on the current state of the object.
   * If there is not enough information to build the link, it clears the
   * current link.
   *
   * Supported URL formats for commit_range_url in k8s-config yaml files:
   * https://<googlesource_repo>/+log/{begin}..{end}
   * https://<github_repo>/commits/{end}
   *
   * GitHub does not support ranges in the URL.
   * When only one commit is being referenced, the {begin}.. is removed
   * from the URL.
   */
  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.
      const isRange = this.isRange();

      if (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;

        // Always replace {end} with the second hash.
        if (url.includes('{end}')) {
          url = url.replace('{end}', this.hashes[1]);
        }
        if (isRange) {
          // Handle range URLs (Googlesource)
          if (url.includes('{begin}')) {
            url = url.replace('{begin}', this.hashes[0]);
          }
        } else {
          // Handle single commit scenarios
          if (url.includes('+log/{begin}..')) {
            // Googlesource style: transform to single commit view
            url = url.replace('+log/{begin}..', '+/');
          } else {
            // Fallback for any other template, remove {begin} if it exists
            if (url.includes('{begin}')) {
              url = url.replace('{begin}', '');
            }
            // If GitHub, show short hash instead of commit number.
            if (url.includes('github')) {
              text = this.hashes[1].substring(0, 7);
            }
          }
        }
        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);
