/**
 * @license
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {parseDate} from '../../../utils/date-util';
import {MessageTag, ReviewerState} from '../../../constants/constants';
import {
  AccountInfo,
  ChangeInfo,
  ChangeMessageInfo,
  ChangeViewChangeInfo,
  ReviewerUpdateInfo,
  Timestamp,
} from '../../../types/common';
import {accountKey} from '../../../utils/account-util';
import {
  FormattedReviewerUpdateInfo,
  ParsedChangeInfo,
} from '../../../types/types';

const MESSAGE_REVIEWERS_THRESHOLD_MILLIS = 500;
const REVIEWER_UPDATE_THRESHOLD_MILLIS = 6000;

interface ChangeInfoParserInput extends ChangeViewChangeInfo {
  messages: ChangeMessageInfo[];
  reviewer_updates: ReviewerUpdateInfo[]; // Always has at least 1 item
}

function isChangeInfoParserInput(
  change: ChangeInfo
): change is ChangeInfoParserInput {
  return !!(
    change.messages &&
    change.reviewer_updates &&
    change.reviewer_updates.length
  );
}

interface ParserBatch {
  author: AccountInfo;
  date: Timestamp;
  type: 'REVIEWER_UPDATE';
  tag: MessageTag.TAG_REVIEWER_UPDATE;
  updates?: UpdateItem[];
}

interface ParserBatchWithNonEmptyUpdates extends ParserBatch {
  updates: UpdateItem[]; // Always has at least 1 items
}

function isParserBatchWithNonEmptyUpdates(
  x: ParserBatch
): x is ParserBatchWithNonEmptyUpdates {
  return !!(x.updates && x.updates.length);
}

interface UpdateItem {
  reviewer: AccountInfo;
  state: ReviewerState;
  prev_state?: ReviewerState;
}

type ReviewersGroupByMessage = {[message: string]: AccountInfo[]};

export class GrReviewerUpdatesParser {
  // TODO(TS): The parser several times reassigns different types to
  // reviewer_updates. After parse complete, the result has ParsedChangeInfo
  // type. This class should be refactored to avoid reassignment.
  private readonly result: ChangeInfoParserInput;

  private batch: ParserBatch | null = null;

  private updateItems: {[accountId: string]: UpdateItem} | null = null;

  private readonly _lastState: {[accountId: string]: ReviewerState} = {};

  constructor(change: ChangeInfoParserInput) {
    this.result = {...change};
  }

  /**
   * Removes messages that describe removed reviewers, since reviewer_updates
   * are used.
   */
  private _filterRemovedMessages() {
    this.result.messages = this.result.messages.filter(
      message => message.tag !== MessageTag.TAG_DELETE_REVIEWER
    );
  }

  /**
   * Is a part of _groupUpdates(). Creates a new batch of updates.
   */
  private _startBatch(update: ReviewerUpdateInfo): ParserBatch {
    this.updateItems = {};
    return {
      author: update.updated_by,
      date: update.updated,
      type: 'REVIEWER_UPDATE',
      tag: MessageTag.TAG_REVIEWER_UPDATE,
    };
  }

  /**
   * Is a part of _groupUpdates(). Validates current batch:
   * - filters out updates that don't change reviewer state.
   * - updates current reviewer state.
   */
  private _completeBatch(batch: ParserBatch) {
    const items = [];
    for (const [accountId, item] of Object.entries(this.updateItems ?? {})) {
      if (this._lastState[accountId] !== item.state) {
        this._lastState[accountId] = item.state;
        items.push(item);
      }
    }
    if (items.length) {
      batch.updates = items;
    }
  }

  /**
   * Groups reviewer updates. Sequential updates are grouped if:
   * - They were performed within short timeframe (6 seconds)
   * - Made by the same person
   * - Non-change updates are discarded within a group
   * - Groups with no-change updates are discarded (eg CC -> CC)
   */
  _groupUpdates(): ParserBatchWithNonEmptyUpdates[] {
    const updates = this.result.reviewer_updates;
    const newUpdates = updates.reduce((newUpdates, update) => {
      if (!this.batch) {
        this.batch = this._startBatch(update);
      }
      const updateDate = parseDate(update.updated).getTime();
      const batchUpdateDate = parseDate(this.batch.date).getTime();
      const reviewerId = accountKey(update.reviewer);
      if (
        updateDate - batchUpdateDate > REVIEWER_UPDATE_THRESHOLD_MILLIS ||
        update.updated_by._account_id !== this.batch.author._account_id
      ) {
        // Next sequential update should form new group.
        this._completeBatch(this.batch);
        if (isParserBatchWithNonEmptyUpdates(this.batch)) {
          newUpdates.push(this.batch);
        }
        this.batch = this._startBatch(update);
      }
      // _startBatch assigns updateItems. When _groupUpdates is calling,
      // batch and updateItems are not set => _startBatch is called. The
      // _startBatch method assigns updateItems
      const updateItems = this.updateItems!;
      updateItems[reviewerId] = {
        reviewer: update.reviewer,
        state: update.state,
      };
      if (this._lastState[reviewerId]) {
        updateItems[reviewerId].prev_state = this._lastState[reviewerId];
      }
      return newUpdates;
    }, [] as ParserBatchWithNonEmptyUpdates[]);
    // reviewer_updates always has at least 1 item
    // (otherwise parse is not created) => updates.reduce calls callback
    // at least once and callback assigns this.batch
    const batch = this.batch!;
    this._completeBatch(batch);
    if (isParserBatchWithNonEmptyUpdates(batch)) {
      newUpdates.push(batch);
    }
    ((this.result
      .reviewer_updates as unknown) as ParserBatchWithNonEmptyUpdates[]) = newUpdates;
    return newUpdates;
  }

  /**
   * Generates update message for reviewer state change.
   */
  private _getUpdateMessage(
    prevReviewerState: string | undefined,
    currentReviewerState: string
  ): string {
    if (prevReviewerState === 'REMOVED' || !prevReviewerState) {
      return `Added to ${currentReviewerState.toLowerCase()}: `;
    } else if (currentReviewerState === 'REMOVED') {
      if (prevReviewerState) {
        return `Removed from ${prevReviewerState.toLowerCase()}: `;
      } else {
        return 'Removed : ';
      }
    } else {
      return `Moved from ${prevReviewerState.toLowerCase()} to ${currentReviewerState.toLowerCase()}: `;
    }
  }

  /**
   * Groups updates for same category (eg CC->CC) into a hash arrays of
   * reviewers.
   */
  _groupUpdatesByMessage(updates: UpdateItem[]): ReviewersGroupByMessage {
    return updates.reduce((result, item) => {
      const message = this._getUpdateMessage(item.prev_state, item.state);
      if (!result[message]) {
        result[message] = [];
      }
      result[message].push(item.reviewer);
      return result;
    }, {} as ReviewersGroupByMessage);
  }

  /**
   * Generates text messages for grouped reviewer updates.
   * Formats reviewer updates to a (not yet implemented) EventInfo instance.
   *
   * @see https://gerrit-review.googlesource.com/c/94490/
   */
  _formatUpdates() {
    const reviewerUpdates = (this.result
      .reviewer_updates as unknown) as ParserBatchWithNonEmptyUpdates[];
    for (const update of reviewerUpdates) {
      const groupedReviewers = this._groupUpdatesByMessage(update.updates);
      const newUpdates: {message: string; reviewers: AccountInfo[]}[] = [];
      for (const [message, reviewers] of Object.entries(groupedReviewers)) {
        newUpdates.push({message, reviewers});
      }
      ((update as unknown) as FormattedReviewerUpdateInfo).updates = newUpdates;
    }
  }

  /**
   * Moves reviewer updates that are within short time frame of change messages
   * back in time so they would come before change messages.
   * TODO(viktard): Remove when server-side serves reviewer updates like so.
   */
  _advanceUpdates() {
    const updates = (this.result
      .reviewer_updates as unknown) as FormattedReviewerUpdateInfo[];
    const messages = this.result.messages;
    messages.forEach((message, index) => {
      const messageDate = parseDate(message.date).getTime();
      const nextMessageDate =
        index === messages.length - 1
          ? null
          : parseDate(messages[index + 1].date).getTime();
      for (const update of updates) {
        const date = parseDate(update.date).getTime();
        if (
          date >= messageDate &&
          (!nextMessageDate || date < nextMessageDate)
        ) {
          const timestamp =
            parseDate(update.date).getTime() -
            MESSAGE_REVIEWERS_THRESHOLD_MILLIS;
          update.date = new Date(timestamp)
            .toISOString()
            .replace('T', ' ')
            .replace('Z', '000000') as Timestamp;
        }
        if (nextMessageDate && date > nextMessageDate) {
          break;
        }
      }
    });
  }

  static parse(
    change: ChangeViewChangeInfo | undefined | null
  ): ParsedChangeInfo | undefined | null {
    // TODO(TS): The !change condition should be removed when all files are converted to TS
    if (!change || !isChangeInfoParserInput(change)) {
      return change;
    }

    const parser = new GrReviewerUpdatesParser(change);
    parser._filterRemovedMessages();
    parser._groupUpdates();
    parser._formatUpdates();
    parser._advanceUpdates();
    return parser.result;
  }
}
