/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  BasePatchSetNum,
  FileInfo,
  FileNameToFileInfoMap,
  PARENT,
  PatchRange,
  PatchSetNumber,
  RevisionPatchSetNum,
} from '../../types/common';
import {combineLatest, of, from, Observable} from 'rxjs';
import {switchMap, map} from 'rxjs/operators';
import {RestApiService} from '../../services/gr-rest-api/gr-rest-api';
import {select} from '../../utils/observable-util';
import {FileInfoStatus, SpecialFilePath} from '../../constants/constants';
import {specialFilePathCompare} from '../../utils/path-list-util';
import {Model} from '../base/model';
import {define} from '../dependency';
import {ChangeModel} from './change-model';
import {CommentsModel} from '../comments/comments-model';
import {Timing} from '../../constants/reporting';
import {ReportingService} from '../../services/gr-reporting/gr-reporting';

export type FileNameToNormalizedFileInfoMap = {
  [name: string]: NormalizedFileInfo;
};
export interface NormalizedFileInfo extends FileInfo {
  __path: string;
  // Compared to `FileInfo` these four props are required here.
  lines_inserted: number;
  lines_deleted: number;
  size_delta: number; // in bytes
  size: number; // in bytes
}

export function normalize(file: FileInfo, path: string): NormalizedFileInfo {
  return {
    __path: path,
    // These 4 props are required in NormalizedFileInfo, but optional in
    // FileInfo. So let's set a default value, if not already set.
    lines_inserted: 0,
    lines_deleted: 0,
    size_delta: 0,
    size: 0,
    ...file,
  };
}

function mapToList(map?: FileNameToFileInfoMap): NormalizedFileInfo[] {
  const list: NormalizedFileInfo[] = [];
  for (const [key, value] of Object.entries(map ?? {})) {
    list.push(normalize(value, key));
  }
  list.sort((f1, f2) => specialFilePathCompare(f1.__path, f2.__path));
  return list;
}

export function addUnmodified(
  files: NormalizedFileInfo[],
  commentedPaths: string[]
) {
  const combined = [...files];
  for (const commentedPath of commentedPaths) {
    if (commentedPath === SpecialFilePath.PATCHSET_LEVEL_COMMENTS) continue;
    if (files.some(f => f.__path === commentedPath)) continue;
    if (
      files.some(
        f => f.status === FileInfoStatus.RENAMED && f.old_path === commentedPath
      )
    ) {
      continue;
    }
    combined.push(
      normalize({status: FileInfoStatus.UNMODIFIED}, commentedPath)
    );
  }
  combined.sort((f1, f2) => specialFilePathCompare(f1.__path, f2.__path));
  return combined;
}

export interface FilesState {
  // TODO: Move reviewed files from change model into here. Change model is
  // already large and complex, so the files model is a better fit.

  /**
   * Basic file and diff information of all files for the currently chosen
   * patch range.
   */
  files: NormalizedFileInfo[];

  /**
   * Basic file and diff information of all files for the left chosen patchset
   * compared against its base (aka parent).
   *
   * Empty if the left chosen patchset is PARENT.
   */
  filesLeftBase: NormalizedFileInfo[];

  /**
   * Basic file and diff information of all files for the right chosen patchset
   * compared against its base (aka parent).
   *
   * Empty if the left chosen patchset is PARENT.
   */
  filesRightBase: NormalizedFileInfo[];
}

const initialState: FilesState = {
  files: [],
  filesLeftBase: [],
  filesRightBase: [],
};

export const filesModelToken = define<FilesModel>('files-model');

export class FilesModel extends Model<FilesState> {
  public readonly files$ = select(this.state$, state => state.files);

  public file$ = (path$: Observable<string | undefined>) =>
    combineLatest([path$, this.files$]).pipe(
      map(([path, files]) => files.find(f => f.__path === path))
    );

  /**
   * `files$` only includes the files that were modified. Here we also include
   * all unmodified files that have comments with
   * `status: FileInfoStatus.UNMODIFIED`.
   */
  public readonly filesIncludingUnmodified$ = select(
    combineLatest([this.files$, this.commentsModel.commentedPaths$]),
    ([files, commentedPaths]) => addUnmodified(files, commentedPaths)
  );

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

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

  constructor(
    readonly changeModel: ChangeModel,
    readonly commentsModel: CommentsModel,
    readonly restApiService: RestApiService,
    private readonly reporting: ReportingService
  ) {
    super(initialState);
    this.subscriptions = [
      this.reportChangeDataStart(),
      this.reportChangeDataEnd(),
      this.subscribeToFiles(
        (psLeft, psRight) => {
          return {basePatchNum: psLeft, patchNum: psRight};
        },
        files => {
          return {files: [...files]};
        }
      ),
      this.subscribeToFiles(
        (psLeft, _) => {
          if (psLeft === PARENT || (psLeft as PatchSetNumber) <= 0)
            return undefined;
          return {basePatchNum: PARENT, patchNum: psLeft as PatchSetNumber};
        },
        files => {
          return {filesLeftBase: [...files]};
        }
      ),
      this.subscribeToFiles(
        (psLeft, psRight) => {
          if (psLeft === PARENT || (psLeft as PatchSetNumber) <= 0)
            return undefined;
          return {basePatchNum: PARENT, patchNum: psRight as PatchSetNumber};
        },
        files => {
          return {filesRightBase: [...files]};
        }
      ),
    ];
  }

  private reportChangeDataStart() {
    return combineLatest([this.changeModel.loading$]).subscribe(
      ([changeLoading]) => {
        if (changeLoading) {
          this.reporting.time(Timing.CHANGE_DATA);
        }
      }
    );
  }

  private reportChangeDataEnd() {
    return combineLatest([this.changeModel.loading$, this.files$]).subscribe(
      ([changeLoading, files]) => {
        if (!changeLoading && files.length > 0) {
          this.reporting.timeEnd(Timing.CHANGE_DATA);
        }
      }
    );
  }

  private subscribeToFiles(
    rangeChooser: (
      basePatchNum: BasePatchSetNum,
      patchNum: RevisionPatchSetNum
    ) => PatchRange | undefined,
    filesToState: (files: NormalizedFileInfo[]) => Partial<FilesState>
  ) {
    return combineLatest([
      this.changeModel.changeNum$,
      this.changeModel.basePatchNum$,
      this.changeModel.patchNum$,
    ])
      .pipe(
        switchMap(([changeNum, basePatchNum, patchNum]) => {
          if (!changeNum || !patchNum) return of({});
          const range = rangeChooser(basePatchNum, patchNum);
          if (!range) return of({});
          return from(
            this.restApiService.getChangeOrEditFiles(changeNum, range)
          );
        }),
        map(mapToList),
        map(filesToState)
      )
      .subscribe(state => {
        this.updateState(state);
      });
  }
}
