/**
 * @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 {CodeOwnerService} from './code-owners-service.js';
import {ownerState} from './owner-ui-state.js';

const SUGGESTION_POLLING_INTERVAL = 1000;

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

  constructor() {
    super();
    this.expandSuggestionStateUnsubscriber = undefined;
  }

  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 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: var(--spacing-s);
          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;
        }
        .suggestion-row {
          display: flex;
          flex-direction: row;
          align-items: flex-start;
          border-bottom: 1px solid var(--border-color);
          padding: var(--spacing-s) 0;
        }
        .suggestion-row:last-of-type {
          border-bottom: none;
        }
        .suggestion-row-indicator {
          margin-right: var(--spacing-m);
          visibility: hidden;
          line-height: 26px;
        }
        .suggestion-row-indicator[visible] {
          visibility: visible;
        }
        .suggestion-row-indicator[visible] iron-icon {
          color: var(--link-color);
        }
        .suggestion-group-name {
          width: 200px;
          line-height: 26px;
          text-overflow: ellipsis;
          overflow: hidden;
          padding-right: var(--spacing-l);
          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 {
          flex: 1;
        }
        .fetch-error-content,
        .no-owners-content {
          line-height: 26px;
          flex: 1;
          padding-left: var(--spacing-m);
        }
        .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;
        }
        gr-account-label {
          background-color: var(--background-color-tertiary);
          display: inline-block;
          padding: var(--spacing-xs) var(--spacing-m);
          user-select: none;
          border: 1px solid transparent;
          --label-border-radius: 8px;
          --account-max-length: 100px;
        }
        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]]
              </div>
            </template>
            <template is="dom-if" if="[[!suggestion.error]]">
              <template is="dom-if" if="[[!suggestion.owners.length]]">
                <div class="no-owners-content">
                  <span>Not found</span>
                  <a on-click="_reportDocClick" href="https://gerrit.googlesource.com/plugins/code-owners/+/master/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>
              <ul class="suggested-owners">
                <template
                  is="dom-repeat"
                  items="[[suggestion.owners]]"
                  as="owner"
                  index-as="ownerIndex"
                >
                  <gr-account-label
                    data-suggestion-index$="[[suggestionIndex]]"
                    data-owner-index$="[[ownerIndex]]"
                    account="[[owner.account]]"
                    hide-hovercard
                    selected$="[[isSelected(owner)]]"
                    on-click="toggleAccount">
                  </gr-account-label>
                </template>
              </ul>
            </template>
          </li>
        </template>
      </ul>
    `;
  }

  static get properties() {
    return {
      // @input
      change: Object,
      restApi: Object,
      reporting: Object,

      // @internal attributes
      hidden: {
        type: Boolean,
        value: true,
        reflectToAttribute: true,
      },
      ownerService: Object,
      suggestedOwners: Array,
      isLoading: {
        type: Boolean,
        value: true,
      },
      reviewers: {
        type: Array,
      },
      pendingReviewers: Array,
    };
  }

  static get observers() {
    return [
      'onInputChanged(restApi, change)',
      'onReviewerChange(reviewers)',
    ];
  }

  connectedCallback() {
    super.connectedCallback();
    this.expandSuggestionStateUnsubscriber = ownerState
        .onExpandSuggestionChange(expanded => {
          this.hidden = !expanded;
          if (expanded) {
            // this is more of a hack to let reivew 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);

            // start fetching suggestions
            if (!this._suggestionsTimer) {
              this._suggestionsTimer = setInterval(() => {
                this._pollingSuggestions();
              }, SUGGESTION_POLLING_INTERVAL);

              // poll immediately to kick start the fetching
              this.reporting
                  .reportLifeCycle('owners-suggestions-fetching-start');
              this._pollingSuggestions();
            }
          }
        });
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    if (this.expandSuggestionStateUnsubscriber) {
      this.expandSuggestionStateUnsubscriber();
      this.expandSuggestionStateUnsubscriber = undefined;
    }
  }

  onInputChanged(restApi, change) {
    ownerState.expandSuggestion = false;
    if ([restApi, change].includes(undefined)) return;
    this.isLoading = true;
    const ownerService = CodeOwnerService.getOwnerService(this.restApi, change);
    if (this.ownerService && this.ownerService !== ownerService) {
      // abort all pending requests
      this.ownerService.abort();
      clearInterval(this._suggestionsTimer);
      this._suggestionsTimer = null;
    }
    this.ownerService = ownerService;

    // if all approved, no need to show the container
    this.ownerService.areAllFilesApproved().then(approved => {
      if (approved) {
        this.hidden = approved;
      }
    });
  }

  _pollingSuggestions() {
    this.ownerService
        .getSuggestedOwners()
        .then(res => {
          if (res.finished) {
            clearInterval(this._suggestionsTimer);
            this._suggestionsTimer = null;
            const reportDetails = res.suggestions.reduce((details, cur) => {
              details.totalGroups++;
              details.stats.push([cur.files.length, cur.owners ? cur.owners.length : 0]);
              return details;
            }, {totalGroups: 0, stats: []});
            this.reporting.reportLifeCycle('owners-suggestions-fetching-finished', reportDetails);
          }
          this.progressText = res.progress;
          this.isLoading = !res.finished;

          this._updateSuggestions(res.suggestions);

          // in case `_updateAllChips` called before suggestedOwners ready
          // from onReviewerChange
          this._updateAllChips(this._currentReviewers);
        });
  }

  _updateSuggestions(suggestions) {
    // update group names and files, no modification on owners or error
    this.suggestedOwners = suggestions.map(suggestion => {
      return this.formatSuggestionInfo(suggestion);
    });
  }

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

  formatSuggestionInfo(suggestion) {
    const res = {};
    res.groupName = suggestion.groupName;
    res.files = suggestion.files.slice();
    res.owners = (suggestion.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.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[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.forEach((owner, oId) => {
        if (
          accounts.some(account => account._account_id
              === owner.account._account_id)
        ) {
          this.set(
              ['suggestedOwners', sId, 'owners', oId],
              {...owner,
                selected: true,
              }
          );
          hasSelected = true;
        } else {
          this.set(
              ['suggestedOwners', sId, 'owners', oId],
              {...owner, selected: false}
          );
        }
      });
      this.set(['suggestedOwners', sId, 'hasSelected'], hasSelected);
    });
  }

  isSelected(owner) {
    return owner.selected;
  }

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

customElements.define(SuggestOwners.is, SuggestOwners);
