/**
 * @license
 * Copyright (C) 2020 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 {CodeOwnersModelMixin} from './code-owners-model-mixin.js';
import {
  SuggestionsState,
  SuggestionsType,
} from './code-owners-model.js';
import {getDisplayOwnersGroups} from './suggest-owners-util.js';

const SUGGESTION_POLLING_INTERVAL = 1000;

class OwnerGroupFileList extends Polymer.Element {
  static get is() {
    return 'owner-group-file-list';
  }

  static get properties() {
    return {
      files: Array,
    };
  }

  static get template() {
    return Polymer.html`
      <style include="shared-styles">
        :host {
          display: block;
          max-height: 500px;
          overflow: auto;
        }
        span {
          display: inline-block;
          border-radius: var(--border-radius);
          margin-left: var(--spacing-s);
          padding: 0 var(--spacing-m);
          color: var(--primary-text-color);
          font-size: var(--font-size-small);
        }
        .Renamed {
          background-color: var(--dark-remove-highlight-color);
          margin: var(--spacing-s) 0;
        }
      </style>
      <ul>
        <template
          is="dom-repeat"
          items="[[files]]"
          as="file"
        >
          <li>
            [[computeFilePath(file)]]<!--
            --><strong>[[computeFileName(file)]]</strong>
            <template is="dom-if" if="[[file.status]]">
              <span class$="[[file.status]]">
                [[file.status]]
              </span>
            </template>
          </li>
        </template>
      </ul>
    `;
  }

  computeFilePath(file) {
    const parts = file.path.split('/');
    return parts.slice(0, parts.length - 1).join('/') + '/';
  }

  computeFileName(file) {
    const parts = file.path.split('/');
    return parts.pop();
  }
}

customElements.define(OwnerGroupFileList.is, OwnerGroupFileList);

export class SuggestOwners extends CodeOwnersModelMixin(Polymer.Element) {
  static get is() {
    return 'suggest-owners';
  }

  static get template() {
    return Polymer.html`
      <style include="shared-styles">
        :host {
          display: block;
          background-color: var(--view-background-color);
          border: 1px solid var(--view-background-color);
          border-radius: var(--border-radius);
          box-shadow: var(--elevation-level-1);
          padding: 0 var(--spacing-m);
          margin: var(--spacing-m) 0;
        }
        p.loading {
          text-align: center;
        }
        .loadingSpin {
          display: inline-block;
        }
        li {
          list-style: none;
        }
        .suggestion-container {
          /* TODO: TBD */
          max-height: 300px;
          overflow-y: auto;
        }
        .flex-break {
          height: 0;
          flex-basis: 100%;
        }
        .suggestion-row, .show-all-owners-row {
          display: flex;
          flex-direction: row;
          align-items: flex-start;
        }
        .suggestion-row {
          flex-wrap: wrap;
          border-bottom: 1px solid var(--border-color);
          padding: var(--spacing-s) 0;
        }
        .show-all-owners-row {
          padding: var(--spacing-m) var(--spacing-xl) var(--spacing-s);
          justify-content: flex-end;
        }
        .suggestion-row-indicator {
          margin-right: var(--spacing-s);
          visibility: hidden;
          line-height: 26px;
        }
        .suggestion-row-indicator[visible] {
          visibility: visible;
        }
        .suggestion-row-indicator[visible] iron-icon {
          color: var(--link-color);
          vertical-align: top;
          position: relative;
          --iron-icon-height: 18px;
          --iron-icon-width: 18px;
          top: 4px; /* (26-18)/2 - 26px line-height and 18px icon */
        }
        .suggestion-group-name {
          width: 260px;
          line-height: 26px;
          text-overflow: ellipsis;
          overflow: hidden;
          padding-right: var(--spacing-s);
          white-space: nowrap;
        }
        .group-name-content {
          display: flex;
          align-items: center;
        }
        .group-name-content .group-name {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .group-name-prefix {
          padding-left: var(--spacing-s);
          white-space: nowrap;
          color: var(--deemphasized-text-color);
        }
        .suggested-owners {
          --account-gap: var(--spacing-xs);
          --negative-account-gap: calc(-1*var(--account-gap));
          margin: var(--negative-account-gap) 0 0 var(--negative-account-gap);
          flex: 1;
        }
        .fetch-error-content,
        .owned-by-all-users-content,
        .no-owners-content {
          line-height: 26px;
          flex: 1;
          padding-left: var(--spacing-m);
        }

        .owned-by-all-users-content iron-icon {
          width: 16px;
          height: 16px;
          padding-top: 5px;
        }
        
        .fetch-error-content {
          color: var(--error-text-color);
        }
        .no-owners-content a {
          padding-left: var(--spacing-s);
        }
        .no-owners-content a iron-icon {
          width: 16px;
          height: 16px;
          padding-top: 5px;
        }
        gr-account-label {
          display: inline-block;
          padding: var(--spacing-xs) var(--spacing-m);
          user-select: none;
          border: 1px solid transparent;
          --label-border-radius: 8px;
          /* account-max-length defines the max text width inside account-label.
           With 60px the gr-account-label always has width <= 100px and 5 labels
           are always fit in a single row */
          --account-max-length: 60px;
          border: 1px solid var(--border-color);
          margin: var(--account-gap) 0 0 var(--account-gap)
        }
        gr-account-label:focus {
          outline: none;
        }
        gr-account-label:hover {
          box-shadow: var(--elevation-level-1);
          cursor: pointer;
        }
        gr-account-label[selected] {
          background-color: var(--chip-selected-background-color);
          border: 1px solid var(--chip-selected-background-color);
          color: var(--chip-selected-text-color);
        }
        gr-hovercard {
          max-width: 800px;
        }
        .loading {
          display: flex;
          align-content: center;
          align-items: center;
          justify-content: center;
          padding: var(--spacing-m);
        }
        .loadingSpin {
          width: 18px;
          height: 18px;
          margin-right: var(--spacing-m);
        }
      </style>
      <p class="loading" hidden="[[!isLoading]]">
        <span class="loadingSpin"></span>
        [[progressText]]
      </p>
      <ul class="suggestion-container">
        <template
          is="dom-repeat"
          items="[[suggestedOwners]]"
          as="suggestion"
          index-as="suggestionIndex"
        >
          <li class="suggestion-row">
            <div
              class="suggestion-row-indicator"
              visible$="[[suggestion.hasSelected]]"
            >
              <iron-icon icon="gr-icons:check-circle"></iron-icon>
            </div>
            <div class="suggestion-group-name">
              <div class="group-name-content">
                <span class="group-name">
                  [[suggestion.groupName.name]]
                </span>
                <template is="dom-if" if="[[suggestion.groupName.prefix]]">
                  <span class="group-name-prefix">
                    ([[suggestion.groupName.prefix]])
                  </span>
                </template>
                <gr-hovercard hidden="[[suggestion.expanded]]">
                  <owner-group-file-list
                    files="[[suggestion.files]]"
                  >
                  </owner-group-file-list>
                </gr-hovercard>
              </div>
              <owner-group-file-list
                hidden="[[!suggestion.expanded]]"
                files="[[suggestion.files]]"
              ></owner-group-file-list>
            </div>
            <template is="dom-if" if="[[suggestion.error]]">
              <div class="fetch-error-content">
                [[suggestion.error]]
                <a on-click="_showErrorDetails"
              </div>
            </template>
            <template is="dom-if" if="[[!suggestion.error]]">
              <template is="dom-if" if="[[!_areOwnersFound(suggestion.owners)]]">
                <div class="no-owners-content">
                  <span>Not found</span>
                  <a on-click="_reportDocClick" href="https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/how-to-use.md#no-code-owners-found" target="_blank">
                    <iron-icon icon="gr-icons:help-outline" title="read documentation"></iron-icon>
                  </a>
                </div>
              </template>
              <template is="dom-if" if="[[suggestion.owners.owned_by_all_users]]">
                <div class="owned-by-all-users-content">
                  <iron-icon icon="gr-icons:info" ></iron-icon>
                  <span>[[_getOwnedByAllUsersContent(isLoading, suggestedOwners)]]</span>
                </div>
              </template>
              <template is="dom-if" if="[[!suggestion.owners.owned_by_all_users]]">
                <template is="dom-if" if="[[_showAllOwners]]">
                  <div class="flex-break"></div>
                </template>
                <ul class="suggested-owners">
                  <template
                    is="dom-repeat"
                    items="[[suggestion.owners.code_owners]]"
                    as="owner"
                    index-as="ownerIndex"
                  ><!--
                    --><gr-account-label
                      data-suggestion-index$="[[suggestionIndex]]"
                      data-owner-index$="[[ownerIndex]]"
                      account="[[owner.account]]"
                      selected$="[[isSelected(owner)]]"
                      on-click="toggleAccount">
                    </gr-account-label><!--
                --></template>
                </ul>
              </template>
            </template>
          </li>
        </template>
        <li class="show-all-owners-row">
          <label>
            <input
              id="showAllOwnersCheckbox"
              type="checkbox"
              checked="{{_showAllOwners::change}}"
            />
            Show all owners
          </label>
        </li>
      </ul>
    `;
  }

  static get properties() {
    return {
      // @internal attributes
      hidden: {
        type: Boolean,
        value: true,
        reflectToAttribute: true,
        computed: '_isHidden(model.showSuggestions)',
      },
      suggestedOwners: Array,
      isLoading: {
        type: Boolean,
        value: true,
      },
      reviewers: {
        type: Array,
      },
      _reviewersIdSet: {
        type: Object,
        computed: '_getReviewersIdSet(reviewers)',
      },
      pendingReviewers: Array,
      _showAllOwners: {
        type: Boolean,
        value: false,
        observer: '_showAllOwnersChanged',
      },
      _allOwnersByPathMap: {
        type: Object,
        computed:
            `_getOwnersByPathMap(model.suggestionsByTypes.${SuggestionsType.ALL_SUGGESTIONS}.files)`,
      },
    };
  }

  static get observers() {
    return [
      '_onReviewerChanged(reviewers)',
      '_onShowSuggestionsChanged(model.showSuggestions)',
      '_onShowSuggestionsTypeChanged(model.showSuggestions,' +
        'model.selectedSuggestionsType)',
      '_onSuggestionsStateChanged(model.selectedSuggestions.state)',
      '_onSuggestionsFilesChanged(model.selectedSuggestions.files, ' +
        '_allOwnersByPathMap, _reviewersIdSet, model.selectedSuggestionsType,' +
        'model.selectedSuggestions.state)',
      '_onSuggestionsLoadProgressChanged(' +
        'model.selectedSuggestions.loadProgress)',
    ];
  }

  constructor() {
    super();
    // To prevent multiple reporting when switching back and forth showAllOwners
    this.reportedEvents = {};
    for (const suggestionType of Object.values(SuggestionsType)) {
      this.reportedEvents[suggestionType] = {
        fetchingStart: false,
        fetchingFinished: false,
      };
    }
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    this._stopUpdateProgressTimer();
    if (this.modelLoader) {
      this.modelLoader.pauseActiveSuggestedOwnersLoading();
    }
  }

  _onShowSuggestionsChanged(showSuggestions) {
    if (!showSuggestions) {
      return;
    }
    // this is more of a hack to let review input lose focus
    // to avoid suggestion dropdown
    // gr-autocomplete has a internal state for tracking focus
    // that will be canceled if any click happens outside of
    // it's target
    // Can not use `this.async` as it's only available in
    // legacy element mixin which not used in this plugin.
    Polymer.Async.timeOut.run(() => this.click(), 100);
  }

  _onShowSuggestionsTypeChanged(showSuggestion, selectedSuggestionsType) {
    if (!showSuggestion) {
      this.modelLoader.pauseActiveSuggestedOwnersLoading();
      return;
    }
    this.modelLoader.loadSuggestions(selectedSuggestionsType);
    // The progress is updated at the next _progressUpdateTimer tick.
    // Without excplicit call to updateLoadSuggestionsProgress it looks like
    // a slow reaction to checkbox.
    this.modelLoader.updateLoadSelectedSuggestionsProgress();

    if (!this.reportedEvents[selectedSuggestionsType].fetchingStart) {
      this.reportedEvents[selectedSuggestionsType].fetchingStart = true;
      this.reporting.reportLifeCycle('owners-suggestions-fetching-start', {
        type: selectedSuggestionsType,
      });
    }
  }

  _startUpdateProgressTimer() {
    if (this._progressUpdateTimer) return;
    this._progressUpdateTimer = setInterval(() => {
      this.modelLoader.updateLoadSelectedSuggestionsProgress();
    }, SUGGESTION_POLLING_INTERVAL);
  }

  _stopUpdateProgressTimer() {
    if (!this._progressUpdateTimer) return;
    clearInterval(this._progressUpdateTimer);
    this._progressUpdateTimer = undefined;
  }

  _onSuggestionsStateChanged(state) {
    this._stopUpdateProgressTimer();
    if (state === SuggestionsState.Loading) {
      this._startUpdateProgressTimer();
    }
    this.isLoading = state === SuggestionsState.Loading;
  }

  _isHidden(showSuggestions) {
    return !showSuggestions;
  }

  loadPropertiesAfterModelChanged() {
    super.loadPropertiesAfterModelChanged();
    this._stopUpdateProgressTimer();
    this.modelLoader.loadAreAllFilesApproved();
  }

  _getReviewersIdSet(reviewers) {
    return new Set((reviewers || []).map(account => account._account_id));
  }

  _onSuggestionsFilesChanged(files, allOwnersByPathMap, reviewersIdSet,
      selectedSuggestionsType, suggestionsState) {
    if (files === undefined || allOwnersByPathMap === undefined ||
        reviewersIdSet === undefined || selectedSuggestionsType === undefined ||
        suggestionsState === undefined) return;

    const groups = getDisplayOwnersGroups(
        files, allOwnersByPathMap, reviewersIdSet,
        selectedSuggestionsType !== SuggestionsType.ALL_SUGGESTIONS);
    // The updateLoadSuggestionsProgress method also updates suggestions
    this._updateSuggestions(groups);
    this._updateAllChips(this._currentReviewers);

    if (suggestionsState !== SuggestionsState.Loaded) return;
    if (!this.reportedEvents[selectedSuggestionsType].fetchingFinished) {
      this.reportedEvents[selectedSuggestionsType].fetchingFinished = true;
      const reportDetails = groups.reduce((details, cur) => {
        details.totalGroups++;
        details.stats.push([cur.files.length,
          cur.owners && cur.owners.code_owners ?
            cur.owners.code_owners.length : 0]);
        return details;
      }, {totalGroups: 0, stats: [], type: selectedSuggestionsType});
      this.reporting.reportLifeCycle(
          'owners-suggestions-fetching-finished', reportDetails);
    }
  }

  _getOwnersByPathMap(files) {
    return new Map((files || [])
        .filter(file => !file.info.error && file.info.owners)
        .map(file => [file.path, file.info.owners])
    );
  }

  _onSuggestionsLoadProgressChanged(progress) {
    this.progressText = progress;
  }

  _updateSuggestions(suggestions) {
    // update group names and files, no modification on owners or error
    const suggestedOwners = suggestions.map(suggestion => {
      return this.formatSuggestionInfo(suggestion);
    });
    // move owned_by_all_users to the bottom:
    const index = suggestedOwners
        .findIndex(suggestion => suggestion.owners.owned_by_all_users);
    if (index >= 0) {
      suggestedOwners.push(suggestedOwners.splice(index, 1)[0]);
    }
    this.suggestedOwners = suggestedOwners;
  }

  _onReviewerChanged(reviewers) {
    this._currentReviewers = reviewers;
    this._updateAllChips(reviewers);
  }

  formatSuggestionInfo(suggestion) {
    const res = {};
    res.groupName = suggestion.groupName;
    res.files = suggestion.files.slice();
    if (suggestion.owners) {
      const codeOwners = (suggestion.owners.code_owners || []).map(owner => {
        const updatedOwner = {...owner};
        const reviewers = this.change.reviewers.REVIEWER;
        if (reviewers &&
            reviewers.find(
                reviewer => reviewer._account_id === owner._account_id)
        ) {
          updatedOwner.selected = true;
        }
        return updatedOwner;
      });
      res.owners = {
        owned_by_all_users: !!suggestion.owners.owned_by_all_users,
        code_owners: codeOwners,
      };
    } else {
      res.owners = {
        owned_by_all_users: false,
        code_owners: [],
      };
    }

    res.error = suggestion.error;
    return res;
  }

  addAccount(owner) {
    owner.selected = true;
    this.dispatchEvent(
        new CustomEvent('add-reviewer', {
          detail: {
            reviewer: {...owner.account, _pendingAdd: true},
          },
          composed: true,
          bubbles: true,
        })
    );
    this.reporting.reportInteraction('add-reviewer');
  }

  removeAccount(owner) {
    owner.selected = false;
    this.dispatchEvent(
        new CustomEvent('remove-reviewer', {
          detail: {
            reviewer: {...owner.account, _pendingAdd: true},
          },
          composed: true,
          bubbles: true,
        })
    );
    this.reporting.reportInteraction('remove-reviewer');
  }

  toggleAccount(e) {
    const grAccountLabel = e.currentTarget;
    const owner = this.suggestedOwners[grAccountLabel.dataset.suggestionIndex]
        .owners.code_owners[grAccountLabel.dataset.ownerIndex];
    if (this.isSelected(owner)) {
      this.removeAccount(owner);
    } else {
      this.addAccount(owner);
    }
  }

  _updateAllChips(accounts) {
    if (!this.suggestedOwners || !accounts) return;
    // update all occurences
    this.suggestedOwners.forEach((suggestion, sId) => {
      let hasSelected = false;
      suggestion.owners.code_owners.forEach((owner, oId) => {
        if (accounts.some(
            account => account._account_id === owner.account._account_id)) {
          this.set(
              ['suggestedOwners', sId, 'owners', 'code_owners', oId],
              {...owner,
                selected: true,
              }
          );
          hasSelected = true;
        } else {
          this.set(
              ['suggestedOwners', sId, 'owners', 'code_owners', oId],
              {...owner, selected: false}
          );
        }
      });
      const nonServiceUser = account =>
        !account.tags || account.tags.indexOf('SERVICE_USER') < 0;
      if (suggestion.owners.owned_by_all_users &&
          accounts.some(nonServiceUser)) {
        hasSelected = true;
      }
      this.set(['suggestedOwners', sId, 'hasSelected'], hasSelected);
    });
  }

  isSelected(owner) {
    return owner.selected;
  }

  _reportDocClick() {
    this.reporting.reportInteraction('code-owners-doc-click',
        {section: 'no owners found'});
  }

  _areOwnersFound(owners) {
    return owners.code_owners.length > 0 || !!owners.owned_by_all_users;
  }

  _getOwnedByAllUsersContent(isLoading, suggestedOwners) {
    if (isLoading) {
      return 'Any user can approve';
    }
    // If all users own all the files in the change suggestedOwners.length === 1
    // (suggestedOwners - collection of owners groupbed by owners)
    return suggestedOwners && suggestedOwners.length === 1 ?
      'Any user can approve. Please select a user manually' :
      'Any user from the other files can approve';
  }

  _showAllOwnersChanged(showAll) {
    // The first call to this method happens before model is set.
    if (!this.model) return;
    this.model.setSelectedSuggestionType(showAll ?
      SuggestionsType.ALL_SUGGESTIONS : SuggestionsType.BEST_SUGGESTIONS);
  }
}

customElements.define(SuggestOwners.is, SuggestOwners);
