/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {combineLatest, fromEvent, Observable} from 'rxjs';
import {
  filter,
  map,
  startWith,
  switchMap,
  tap,
  withLatestFrom,
} from 'rxjs/operators';
import {RepoName, BranchName, TopicName, ChangeInfo} from '../../api/rest-api';
import {NavigationService} from '../../elements/core/gr-navigation/gr-navigation';
import {RestApiService} from '../../services/gr-rest-api/gr-rest-api';
import {GerritView} from '../../services/router/router-model';
import {accountKey} from '../../utils/account-util';
import {select} from '../../utils/observable-util';
import {escapeAndWrapSearchOperatorValue} from '../../utils/string-util';
import {encodeURL, getBaseUrl} from '../../utils/url-util';
import {define, Provider} from '../dependency';
import {Model} from '../base/model';
import {UserModel} from '../user/user-model';
import {ViewState} from './base';
import {createChangeUrl} from './change';

const USER_QUERY_PATTERN = /^owner:\s?("[^"]+"|[^ ]+)$/;

const REPO_QUERY_PATTERN =
  /^project:\s?("[^"]+"|[^ ]+)(\sstatus\s?:(open|"open"))?$/;

const LOOKUP_QUERY_PATTERNS: RegExp[] = [
  /^\s*i?[0-9a-f]{7,40}\s*$/i, // CHANGE_ID
  /^\s*[1-9][0-9]*\s*$/g, // CHANGE_NUM
  /[0-9a-f]{40}/, // COMMIT
];

export interface SearchViewState extends ViewState {
  view: GerritView.SEARCH;

  /**
   * The query for searching changes.
   *
   * Changing this to something non-empty will trigger search.
   */
  query: string;

  /**
   * How many initial search results should be skipped? This is for showing
   * more than one search result page. This must be a non-negative number.
   * If the string is not provided or cannot be parsed as expected, then the
   * offset falls back to 0.
   *
   * TODO: Consider converting from string to number before writing to the
   * state object.
   */
  offset?: string;

  /**
   * Is a search API call currrently in progress?
   */
  loading: boolean;

  /**
   * The search results for the current query.
   * `undefined` must be allowed here, because updating state with a partial
   * state without `changes` must be possible without overwriting existing
   * changes.
   * TODO: We should consider moving `changes` to a another model. This is not
   * really "view" state. View state must directly correlate to the URL.
   */
  changes?: ChangeInfo[];
}

export interface SearchUrlOptions {
  query?: string;
  offset?: number;
  repo?: RepoName;
  branch?: BranchName;
  topic?: TopicName;
  statuses?: string[];
  hashtag?: string;
  owner?: string;
}

export function createSearchUrl(params: SearchUrlOptions): string {
  let offsetExpr = '';
  if (params.offset && params.offset > 0) {
    offsetExpr = `,${params.offset}`;
  }

  if (params.query) {
    return `${getBaseUrl()}/q/${encodeURL(params.query)}${offsetExpr}`;
  }

  const operators: string[] = [];
  if (params.owner) {
    operators.push('owner:' + encodeURL(params.owner));
  }
  if (params.repo) {
    operators.push('project:' + encodeURL(params.repo));
  }
  if (params.branch) {
    operators.push('branch:' + encodeURL(params.branch));
  }
  if (params.topic) {
    operators.push(
      'topic:' + escapeAndWrapSearchOperatorValue(encodeURL(params.topic))
    );
  }
  if (params.hashtag) {
    operators.push(
      'hashtag:' +
        escapeAndWrapSearchOperatorValue(
          encodeURL(params.hashtag.toLowerCase())
        )
    );
  }
  if (params.statuses) {
    if (params.statuses.length === 1) {
      operators.push('status:' + encodeURL(params.statuses[0]));
    } else if (params.statuses.length > 1) {
      operators.push(
        '(' +
          params.statuses.map(s => `status:${encodeURL(s)}`).join(' OR ') +
          ')'
      );
    }
  }

  return `${getBaseUrl()}/q/${operators.join('+')}${offsetExpr}`;
}

export const searchViewModelToken =
  define<SearchViewModel>('search-view-model');

/**
 * This is the view model for the search page.
 *
 * It keeps track of the overall search view state and provides selectors for
 * subscribing to certain slices of the state.
 *
 * It manages loading the changes to be shown on the search page by providing
 * `changes` in its state. Changes to the view state or certain user preferences
 * will automatically trigger reloading the changes.
 */
export class SearchViewModel extends Model<SearchViewState | undefined> {
  public readonly query$ = select(this.state$, s => s?.query ?? '');

  private readonly offset$ = select(this.state$, s => s?.offset ?? '0');

  /**
   * Convenience selector for getting the `offset` as a number.
   *
   * TODO: Consider changing the type of `offset$` and `state.offset` to
   * `number`.
   */
  public readonly offsetNumber$ = select(this.offset$, offset => {
    const offsetNumber = Number(offset);
    return Number.isFinite(offsetNumber) ? offsetNumber : 0;
  });

  public readonly changes$ = select(this.state$, s => s?.changes ?? []);

  public readonly userId$ = select(
    combineLatest([this.query$, this.changes$]),
    ([query, changes]) => {
      if (changes.length === 0) return undefined;
      if (!USER_QUERY_PATTERN.test(query)) return undefined;
      const ownerKey = accountKey(changes[0].owner);
      if (changes.some(change => accountKey(change.owner) !== ownerKey)) {
        return undefined;
      }
      return ownerKey;
    }
  );

  public readonly repo$ = select(
    combineLatest([this.query$, this.changes$]),
    ([query, changes]) => {
      if (changes.length === 0) return undefined;
      if (!REPO_QUERY_PATTERN.test(query)) return undefined;
      return changes[0].project;
    }
  );

  public readonly loading$ = select(this.state$, s => s?.loading ?? false);

  // For usage in `combineLatest` we need `startWith` such that reload$ has an
  // initial value.
  private readonly reload$: Observable<unknown> = fromEvent(
    document,
    'reload'
  ).pipe(startWith(undefined));

  private readonly reloadChangesTrigger$ = combineLatest([
    this.reload$,
    this.query$,
    this.offsetNumber$,
    this.userModel.preferenceChangesPerPage$,
  ]).pipe(
    map(([_reload, query, offsetNumber, changesPerPage]) => {
      const params: [string, number, number] = [
        query,
        offsetNumber,
        changesPerPage,
      ];
      return params;
    })
  );

  constructor(
    private readonly restApiService: RestApiService,
    private readonly userModel: UserModel,
    private readonly getNavigation: Provider<NavigationService>
  ) {
    super(undefined);
    this.subscriptions = [
      this.reloadChangesTrigger$
        .pipe(
          switchMap(a => this.reloadChanges(a)),
          tap(changes => this.updateState({changes, loading: false}))
        )
        .subscribe(),
      this.changes$
        .pipe(
          filter(changes => changes.length === 1),
          withLatestFrom(this.query$)
        )
        .subscribe(([changes, query]) =>
          this.redirectSingleResult(query, changes)
        ),
    ];
  }

  private async reloadChanges([query, offset, changesPerPage]: [
    string,
    number,
    number
  ]): Promise<ChangeInfo[]> {
    if (this.getState() === undefined) return [];
    if (query.trim().length === 0) return [];
    this.updateState({loading: true});
    const changes = await this.restApiService.getChanges(
      changesPerPage,
      query,
      offset
    );
    return changes ?? [];
  }

  // visible for testing
  redirectSingleResult(query: string, changes: ChangeInfo[]): void {
    if (changes.length !== 1) return;
    for (const queryPattern of LOOKUP_QUERY_PATTERNS) {
      if (query.match(queryPattern)) {
        // "Back"/"Forward" buttons work correctly only with replaceUrl()
        this.getNavigation().replaceUrl(createChangeUrl({change: changes[0]}));
        return;
      }
    }
  }
}
