/**
 * @license
 * Copyright 2023 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  ChangeInfo,
  RelatedChangeAndCommitInfo,
  SubmittedTogetherInfo,
} from '../../types/common';
import {RestApiService} from '../../services/gr-rest-api/gr-rest-api';
import {select} from '../../utils/observable-util';
import {Model} from '../base/model';
import {define} from '../dependency';
import {ChangeModel} from './change-model';
import {combineLatest, forkJoin, from, of} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {ConfigModel} from '../config/config-model';
import {ChangeStatus} from '../../api/rest-api';
import {isDefined} from '../../types/types';

export interface RelatedChangesState {
  /** `undefined` means "not yet loaded". */
  relatedChanges?: RelatedChangeAndCommitInfo[];
  submittedTogether?: SubmittedTogetherInfo;
  cherryPicks?: ChangeInfo[];
  conflictingChanges?: ChangeInfo[];
  sameTopicChanges?: ChangeInfo[];
  revertingChanges: ChangeInfo[];
}

const initialState: RelatedChangesState = {
  relatedChanges: undefined,
  submittedTogether: undefined,
  cherryPicks: undefined,
  conflictingChanges: undefined,
  sameTopicChanges: undefined,
  revertingChanges: [],
};

export const relatedChangesModelToken = define<RelatedChangesModel>(
  'related-changes-model'
);

export class RelatedChangesModel extends Model<RelatedChangesState> {
  public readonly relatedChanges$ = select(
    this.state$,
    state => state.relatedChanges
  );

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

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

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

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

  /**
   * Emits all changes that have reverted the current change, based on
   * information from parsed change messages. Abandoned changes are not
   * included.
   */
  public readonly revertingChanges$ = select(
    this.state$,
    state => state.revertingChanges
  );

  /**
   * Emits one reverting change (if there is any) from revertingChanges$.
   * It prefers MERGED changes. Otherwise the choice is random.
   */
  public readonly revertingChange$ = select(
    this.revertingChanges$,
    revertingChanges => {
      if (revertingChanges.length === 0) return undefined;
      const submittedRevert = revertingChanges.find(
        c => c.status === ChangeStatus.MERGED
      );
      if (submittedRevert) return submittedRevert;
      return revertingChanges[0];
    }
  );

  /**
   * Determines whether the change has a parent change. If there
   * is a relation chain, and the change id is not the last item of the
   * relation chain, then there is a parent.
   */
  public readonly hasParent$ = select(
    combineLatest([this.changeModel.change$, this.relatedChanges$]),
    ([change, relatedChanges]) => {
      if (!change) return undefined;
      if (relatedChanges === undefined) return undefined;
      if (relatedChanges.length === 0) return false;
      const lastChangeId = relatedChanges[relatedChanges.length - 1].change_id;
      return lastChangeId !== change.change_id;
    }
  );

  constructor(
    readonly changeModel: ChangeModel,
    readonly configModel: ConfigModel,
    readonly restApiService: RestApiService
  ) {
    super(initialState);
    this.subscriptions = [
      this.loadRelatedChanges(),
      this.loadSubmittedTogether(),
      this.loadCherryPicks(),
      this.loadConflictingChanges(),
      this.loadSameTopicChanges(),
      this.loadRevertingChanges(),
    ];
  }

  private loadRelatedChanges() {
    return combineLatest([
      this.changeModel.changeNum$,
      this.changeModel.latestPatchNum$,
    ])
      .pipe(
        switchMap(([changeNum, latestPatchNum]) => {
          if (!changeNum || !latestPatchNum) return of(undefined);
          return from(
            this.restApiService
              .getRelatedChanges(changeNum, latestPatchNum)
              .then(info => info?.changes ?? [])
          );
        })
      )
      .subscribe(relatedChanges => {
        this.updateState({relatedChanges});
      });
  }

  private loadSubmittedTogether() {
    return this.changeModel.changeNum$
      .pipe(
        switchMap(changeNum => {
          if (!changeNum) return of(undefined);
          return from(
            this.restApiService.getChangesSubmittedTogether(changeNum)
          );
        })
      )
      .subscribe(submittedTogether => {
        this.updateState({submittedTogether});
      });
  }

  private loadCherryPicks() {
    return combineLatest([
      this.changeModel.branch$,
      this.changeModel.changeId$,
      this.changeModel.repo$,
    ])
      .pipe(
        switchMap(([branch, changeId, repo]) => {
          if (!branch || !changeId || !repo) return of(undefined);
          return from(
            this.restApiService.getChangeCherryPicks(repo, changeId, branch)
          );
        })
      )
      .subscribe(cherryPicks => {
        this.updateState({cherryPicks});
      });
  }

  private loadConflictingChanges() {
    return combineLatest([
      this.changeModel.changeNum$,
      this.changeModel.status$,
      this.changeModel.mergeable$,
    ])
      .pipe(
        switchMap(([changeNum, status, mergeable]) => {
          if (!changeNum || !status || !mergeable) return of(undefined);
          if (status !== ChangeStatus.NEW) return of(undefined);
          return from(this.restApiService.getChangeConflicts(changeNum));
        })
      )
      .subscribe(conflictingChanges => {
        this.updateState({conflictingChanges});
      });
  }

  private loadSameTopicChanges() {
    return combineLatest([
      this.changeModel.changeNum$,
      this.changeModel.topic$,
      this.configModel.serverConfig$,
    ])
      .pipe(
        switchMap(([changeNum, topic, config]) => {
          if (!changeNum || !topic || !config) return of(undefined);
          if (config.change.submit_whole_topic) return of(undefined);
          return from(
            this.restApiService.getChangesWithSameTopic(topic, {
              openChangesOnly: true,
              changeToExclude: changeNum,
            })
          );
        })
      )
      .subscribe(sameTopicChanges => {
        this.updateState({sameTopicChanges});
      });
  }

  private loadRevertingChanges() {
    return this.changeModel.revertingChangeIds$
      .pipe(
        switchMap(changeIds => {
          if (!changeIds?.length) return of([]);
          return forkJoin(
            changeIds.map(changeId =>
              from(this.restApiService.getChange(changeId))
            )
          );
        }),
        map(changes => changes.filter(isDefined)),
        map(changes => changes.filter(c => c.status !== ChangeStatus.ABANDONED))
      )
      .subscribe(revertingChanges => {
        this.updateState({revertingChanges});
      });
  }
}
