/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  NumericChangeId,
  RepoName,
  RevisionPatchSetNum,
  BasePatchSetNum,
  ChangeInfo,
  PatchSetNumber,
  EDIT,
  PARENT,
} from '../../api/rest-api';
import {Tab} from '../../constants/constants';
import {GerritView} from '../../services/router/router-model';
import {UrlEncodedCommentId} from '../../types/common';
import {assertIsDefined, toggleSet} from '../../utils/common-util';
import {select} from '../../utils/observable-util';
import {
  encodeURL,
  getBaseUrl,
  getPatchRangeExpression,
} from '../../utils/url-util';
import {AttemptChoice} from '../checks/checks-util';
import {define} from '../dependency';
import {Model} from '../base/model';
import {ViewState} from './base';
import {isNumber} from '../../utils/patch-set-util';

export enum ChangeChildView {
  OVERVIEW = 'OVERVIEW',
  DIFF = 'DIFF',
  EDIT = 'EDIT',
}

export interface ChangeViewState extends ViewState {
  view: GerritView.CHANGE;
  childView: ChangeChildView;

  changeNum: NumericChangeId;
  repo: RepoName;
  patchNum?: RevisionPatchSetNum;
  basePatchNum?: BasePatchSetNum;
  /** Refers to comment on COMMENTS tab in OVERVIEW. */
  commentId?: UrlEncodedCommentId;

  // TODO: Move properties that only apply to OVERVIEW into a submessage.

  edit?: boolean;
  /** This can be a string only for plugin provided tabs. */
  tab?: Tab | string;

  // TODO: Move properties that only apply to CHECKS tab into a submessage.

  /** Checks related view state */

  /** selected patchset for check runs (undefined=latest) */
  checksPatchset?: PatchSetNumber;
  /** regular expression for filtering check runs */
  filter?: string;
  /** selected attempt for check runs (undefined=latest) */
  attempt?: AttemptChoice;
  /** selected check runs identified by `checkName` */
  checksRunsSelected?: Set<string>;
  /** regular expression for filtering check results */
  checksResultsFilter?: string;

  /** State properties that trigger one-time actions */

  /** for scrolling a Change Log message into view in gr-change-view */
  messageHash?: string;
  /**
   * For logging where the user came from. This is handled by the router, so
   * this is not inspected by the model.
   */
  usp?: string;
  /**
   * Triggers all change related data to be reloaded. This is implemented by
   * intercepting change view state updates and `forceReload` causing the view
   * state to be wiped clean as `undefined` in an intermediate update.
   */
  forceReload?: boolean;
  /** triggers opening the reply dialog */
  openReplyDialog?: boolean;

  /** These properties apply to the DIFF child view only. */
  diffView?: {
    path: string;
    // TODO: Use LineNumber as a type, i.e. accept FILE and LOST.
    lineNum?: number;
    leftSide?: boolean;
  };

  /** These properties apply to the EDIT child view only. */
  editView?: {
    path: string;
    lineNum?: number;
  };
}

export type DiffViewState = Partial<ChangeViewState> & {
  patchNum: RevisionPatchSetNum;
  diffView: {
    path: string;
    lineNum?: number;
    leftSide?: boolean;
  };
};

export type EditViewState = Partial<ChangeViewState> & {
  patchNum: RevisionPatchSetNum;
  editView: {
    path: string;
    lineNum?: number;
  };
};

/**
 * This is a convenience type such that you can pass a `ChangeInfo` object
 * as the `change` property instead of having to set both the `changeNum` and
 * `project` properties explicitly.
 */
export type CreateChangeUrlObject = Omit<
  ChangeViewState,
  'view' | 'childView' | 'changeNum' | 'repo'
> & {
  change: Pick<ChangeInfo, '_number' | 'project'>;
};

export function isCreateChangeUrlObject(
  state: CreateChangeUrlObject | Omit<ChangeViewState, 'view'>
): state is CreateChangeUrlObject {
  return !!(state as CreateChangeUrlObject).change;
}

export function objToState(
  obj:
    | (CreateChangeUrlObject & {childView: ChangeChildView})
    | Omit<ChangeViewState, 'view'>
): ChangeViewState {
  if (isCreateChangeUrlObject(obj)) {
    return {
      ...obj,
      view: GerritView.CHANGE,
      changeNum: obj.change._number,
      repo: obj.change.project,
    };
  }
  return {...obj, view: GerritView.CHANGE};
}

export function createChangeViewUrl(state: ChangeViewState): string {
  switch (state.childView) {
    case ChangeChildView.OVERVIEW:
      return createChangeUrl(state);
    case ChangeChildView.DIFF:
      return createDiffUrl(state);
    case ChangeChildView.EDIT:
      return createEditUrl(state);
  }
}

export function createChangeUrl(
  obj: CreateChangeUrlObject | Omit<ChangeViewState, 'view' | 'childView'>
): string {
  const state: ChangeViewState = objToState({
    ...obj,
    childView: ChangeChildView.OVERVIEW,
  });

  let suffix = '';
  const queries = [];
  if (state.checksPatchset && state.checksPatchset > 0) {
    queries.push(`checksPatchset=${state.checksPatchset}`);
  }
  if (state.attempt) {
    if (state.attempt !== 'latest') queries.push(`attempt=${state.attempt}`);
  }
  if (state.filter) {
    queries.push(`filter=${state.filter}`);
  }
  if (state.checksResultsFilter) {
    queries.push(`checksResultsFilter=${state.checksResultsFilter}`);
  }
  if (state.checksRunsSelected && state.checksRunsSelected.size > 0) {
    queries.push(`checksRunsSelected=${[...state.checksRunsSelected].sort()}`);
  }
  if (state.tab && state.tab !== Tab.FILES) {
    queries.push(`tab=${state.tab}`);
  }
  if (state.forceReload) {
    queries.push('forceReload=true');
  }
  if (state.openReplyDialog) {
    queries.push('openReplyDialog=true');
  }
  if (state.usp) {
    queries.push(`usp=${state.usp}`);
  }
  if (state.edit) {
    suffix += ',edit';
  }
  if (state.commentId) {
    suffix += `/comments/${state.commentId}`;
  }
  if (queries.length > 0) {
    suffix += '?' + queries.join('&');
  }
  if (state.messageHash) {
    suffix += state.messageHash;
  }

  return `${createChangeUrlCommon(state)}${suffix}`;
}

export function createDiffUrl(
  obj: CreateChangeUrlObject | Omit<ChangeViewState, 'view' | 'childView'>
): string {
  const state: ChangeViewState = objToState({
    ...obj,
    childView: ChangeChildView.DIFF,
  });

  let path = `/${encodeURL(state.diffView?.path ?? '')}`;
  // TODO: Move creating of comment URLs to a separate function. We are
  // "abusing" the `commentId` property, which should only be used for pointing
  // to comment in the COMMENTS tab of the OVERVIEW page.
  if (state.commentId) {
    path += `comment/${state.commentId}/`;
  }

  let queryParams = '';
  const params = [];
  if (state.checksPatchset && state.checksPatchset > 0) {
    params.push(`checksPatchset=${state.checksPatchset}`);
  }
  if (params.length > 0) {
    queryParams = '?' + params.join('&');
  }

  let hash = '';
  if (state.diffView?.lineNum) {
    hash += '#';
    if (state.diffView?.leftSide) {
      hash += 'b';
    }
    hash += state.diffView.lineNum;
  }

  return `${createChangeUrlCommon(state)}${path}${queryParams}${hash}`;
}

export function createEditUrl(
  obj: Omit<ChangeViewState, 'view' | 'childView'>
): string {
  const state: ChangeViewState = objToState({
    ...obj,
    childView: ChangeChildView.DIFF,
    patchNum: obj.patchNum ?? EDIT,
  });

  const path = `/${encodeURL(state.editView?.path ?? '')}`;
  const line = state.editView?.lineNum;
  const suffix = line ? `#${line}` : '';

  return `${createChangeUrlCommon(state)}${path},edit${suffix}`;
}

/**
 * The shared part of creating a change URL between OVERVIEW, DIFF and EDIT
 * child views.
 */
function createChangeUrlCommon(state: ChangeViewState) {
  let range = getPatchRangeExpression(state);
  if (range.length) range = '/' + range;

  let repo = '';
  if (state.repo) repo = `${encodeURL(state.repo)}/+/`;

  return `${getBaseUrl()}/c/${repo}${state.changeNum}${range}`;
}

export const changeViewModelToken =
  define<ChangeViewModel>('change-view-model');

export class ChangeViewModel extends Model<ChangeViewState | undefined> {
  public readonly changeNum$ = select(this.state$, state => state?.changeNum);

  public readonly patchNum$ = select(this.state$, state => state?.patchNum);

  public readonly basePatchNum$ = select(
    this.state$,
    state => state?.basePatchNum
  );

  public readonly openReplyDialog$ = select(
    this.state$,
    state => state?.openReplyDialog
  );

  public readonly commentId$ = select(this.state$, state => state?.commentId);

  public readonly edit$ = select(this.state$, state => !!state?.edit);

  public readonly editPath$ = select(
    this.state$,
    state => state?.editView?.path
  );

  public readonly diffPath$ = select(
    this.state$,
    state => state?.diffView?.path
  );

  public readonly diffLine$ = select(
    this.state$,
    state => state?.diffView?.lineNum
  );

  public readonly diffLeftSide$ = select(
    this.state$,
    state => state?.diffView?.leftSide ?? false
  );

  public readonly childView$ = select(this.state$, state => state?.childView);

  public readonly tab$ = select(this.state$, state => {
    if (state?.tab) return state.tab;
    if (state?.commentId) return Tab.COMMENT_THREADS;
    return Tab.FILES;
  });

  public readonly checksPatchset$ = select(
    this.state$,
    state => state?.checksPatchset
  );

  public readonly attempt$ = select(this.state$, state => state?.attempt);

  public readonly filter$ = select(this.state$, state => state?.filter);

  public readonly checksResultsFilter$ = select(
    this.state$,
    state => state?.checksResultsFilter ?? ''
  );

  public readonly checksRunsSelected$ = select(
    this.state$,
    state => state?.checksRunsSelected ?? new Set<string>()
  );

  constructor() {
    super(undefined);
    this.state$.subscribe(s => {
      if (s?.usp || s?.forceReload || s?.openReplyDialog) {
        this.updateState({
          usp: undefined,
          forceReload: undefined,
          openReplyDialog: undefined,
        });
      }
    });
    document.addEventListener('reload', this.reload);
  }

  override finalize(): void {
    document.removeEventListener('reload', this.reload);
  }

  /**
   * Calling this is the same as firing the 'reload' event. This is also the
   * same as adding `forceReload` parameter in the URL. See below.
   */
  reload = () => {
    const state = this.getState();
    if (state !== undefined) this.forceLoad(state);
  };

  /**
   * This is the destination of where the `reload()` method, the `reload` event
   * and the `forceReload` URL parameter all end up.
   */
  private forceLoad(state: ChangeViewState) {
    this.setState(undefined);
    // We have to do this in a timeout, because we need the `undefined` value to
    // be processed by all observers first and thus have the "reset" completed.
    setTimeout(() => this.setState({...state, forceReload: undefined}));
  }

  override setState(state: ChangeViewState | undefined): void {
    if (state?.forceReload) {
      this.forceLoad(state);
    } else {
      super.setState(state);
    }
  }

  /**
   * Wrapper around createDiffUrl() that falls back to the current state for all
   * properties that are not explicitly provided as an override.
   */
  diffUrl(override: DiffViewState): string {
    const current = this.getState();
    assertIsDefined(current?.changeNum);
    assertIsDefined(current?.repo);

    const patchNum = override.patchNum ?? current.patchNum;
    let basePatchNum = override.basePatchNum ?? current.basePatchNum;
    if (isNumber(basePatchNum) && isNumber(patchNum)) {
      if ((patchNum as number) <= (basePatchNum as number)) {
        basePatchNum = PARENT;
      }
    }
    return createDiffUrl({
      changeNum: override.changeNum ?? current.changeNum,
      repo: override.repo ?? current.repo,
      patchNum,
      basePatchNum,
      checksPatchset: override.checksPatchset ?? current.checksPatchset,
      diffView: override.diffView ?? current.diffView,
    });
  }

  /**
   * Wrapper around createEditUrl() that falls back to the current state for all
   * properties that are not explicitly provided as an override.
   */
  editUrl(override: EditViewState): string {
    const current = this.getState();
    assertIsDefined(current?.changeNum);
    assertIsDefined(current?.repo);

    return createEditUrl({
      changeNum: override.changeNum ?? current.changeNum,
      repo: override.repo ?? current.repo,
      patchNum: override.patchNum ?? current.patchNum,
      editView: override.editView ?? current.editView,
    });
  }

  toggleSelectedCheckRun(checkName: string) {
    const current = this.getState()?.checksRunsSelected ?? new Set();
    const next = new Set(current);
    toggleSet(next, checkName);
    this.updateState({checksRunsSelected: next});
  }
}
