/**
 * @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 {OwnerStatus} from './code-owners-fetcher.js';
import {CodeOwnersModelMixin} from './code-owners-model-mixin.js';
import {showPluginFailedMessage} from './code-owners-banner.js';
import {isPluginErrorState, UserRole} from './code-owners-model.js';

/**
 * Owner requirement control for `submit-requirement-item-code-owners` endpoint.
 *
 * This will show the status and suggest owners button next to
 * the code-owners submit requirement.
 */
export class OwnerRequirementValue extends
  CodeOwnersModelMixin(Polymer.Element) {
  static get is() {
    return 'owner-requirement-value';
  }

  static get template() {
    return Polymer.html`
        <style include="shared-styles">
        :host {
          --gr-button: {
            padding: 0px;
          }
        }
        p.loading {
          display: flex;
          align-content: center;
          align-items: center;
          justify-content: center;
        }
        .loadingSpin {
          display: inline-block;
          margin-right: var(--spacing-m);
          width: 18px;
          height: 18px;
        }
        gr-button {
          padding-left: var(--spacing-m);
        }
        gr-button::part(paper-button) {
          padding: 0 var(--spacing-s);
        }
        a {
          text-decoration: none;
        }
        </style>
        <p class="loading" hidden="[[!_isLoading]]">
          <span class="loadingSpin"></span>
          Loading status ...
        </p>
        <template is="dom-if" if="[[!_isLoading]]">
          <template is="dom-if" if="[[!_pluginFailed(model.pluginStatus)]]">
            <template is="dom-if" if="[[!model.branchConfig.no_code_owners_defined]]">
              <template is="dom-if" if="[[!_newerPatchsetUploaded]]">
                <span>[[_computeStatusText(_statusCount, _isOverriden)]]</span>
                <template is="dom-if" if="[[_overrideInfoUrl]]">
                  <a on-click="_reportDocClick" href="[[_overrideInfoUrl]]"
                    target="_blank">
                    <iron-icon icon="gr-icons:help-outline"
                      title="Documentation for overriding code owners"></iron-icon>
                  </a>
                </template>
                <template is="dom-if" if="[[_isSignedInUser]]">
                  <gr-button link on-click="_openReplyDialog">
                    [[_getSuggestOwnersText(_statusCount)]]
                  </gr-button>
                </template>
              </template>
              <template is="dom-if" if="[[_newerPatchsetUploaded]]">
                <span>A newer patch set has been uploaded.</span>
              </template>
            </template>
            <template is="dom-if" if="[[model.branchConfig.no_code_owners_defined]]">
              <span>No code-owners file</span>
              <a href="https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/user-guide.md#how-to-submit-changes-with-files-that-have-no-code-owners" target="_blank">
                <iron-icon icon="gr-icons:help-outline"
                  title="Documentation about submitting changes with files that have no code owners?"></iron-icon>
              </a>
            </template>
          </template>
          <template is="dom-if" if="[[_pluginFailed(model.pluginStatus)]]">
            <span>Code-owners plugin has failed</span>
            <gr-button link on-click="_showFailDetails">
              Details
            </gr-button>
          </template>
        </template>
      `;
  }

  static get properties() {
    return {
      _statusCount: Object,
      _newerPatchsetUploaded: Boolean,
      _isLoading: {
        type: Boolean,
        computed: '_computeIsLoading(model.branchConfig, model.status, ' +
            'model.userRole, model.pluginStatus)',
      },
      _isOverriden: {
        type: Boolean,
        computed: '_computeIsOverriden(change, model.branchConfig)',
      },
      _overrideInfoUrl: {
        type: String,
        computed: '_computeOverrideInfoUrl(model.branchConfig)',
      },
      _isSignedInUser: {
        type: Boolean,
        computed: '_computeIsSignedInUser(model.userRole)'
      }
    };
  }

  static get observers() {
    return [
      '_onStatusChanged(model.status, model.userRole)',
    ];
  }

  loadPropertiesAfterModelChanged() {
    super.loadPropertiesAfterModelChanged();
    this.reporting.reportLifeCycle('owners-submit-requirement-summary-start');
    this.modelLoader.loadBranchConfig();
    this.modelLoader.loadStatus();
    this.modelLoader.loadUserRole();
  }

  _computeIsLoading(branchConfig, status, userRole, pluginStatus) {
    if (this._pluginFailed(pluginStatus)) {
      return false;
    }
    return !branchConfig || !status || !userRole;
  }

  _computeIsSignedInUser(userRole) {
    return userRole && userRole !== UserRole.ANONYMOUS;
  }

  _pluginFailed(pluginStatus) {
    return pluginStatus && isPluginErrorState(pluginStatus.state);
  }

  _onStatusChanged(status, userRole) {
    if (!status || !userRole) {
      this._statusCount = undefined;
      this._newerPatchsetUploaded = undefined;
      return;
    }
    const rawStatuses = status.rawStatuses;
    this._statusCount = this._getStatusCount(rawStatuses);
    this._newerPatchsetUploaded = status.newerPatchsetUploaded;
    this.reporting.reportLifeCycle('owners-submit-requirement-summary-shown',
        {...this._statusCount, user_role: userRole});
  }

  _computeOverrideInfoUrl(branchConfig) {
    if (!branchConfig) {
      return '';
    }
    return branchConfig.general && branchConfig.general.override_info_url ?
      branchConfig.general.override_info_url : '';
  }

  _computeIsOverriden(change, branchConfig) {
    if (!change || !branchConfig || !branchConfig['override_approval']) {
      // no override labels configured
      return false;
    }

    for (const requiredApprovalInfo of branchConfig['override_approval']) {
      const overridenLabel = requiredApprovalInfo.label;
      const overridenValue = Number(requiredApprovalInfo.value);
      if (isNaN(overridenValue)) continue;

      if (this.change.labels[overridenLabel]) {
        const votes = change.labels[overridenLabel].all || [];
        if (votes.find(v => Number(v.value) >= overridenValue)) {
          return true;
        }
      }
    }

    // otherwise always reset it to false
    return false;
  }

  _getSuggestOwnersText(statusCount) {
    return statusCount && statusCount.missing === 0 ?
      'Add owners' : 'Suggest owners';
  }

  _getStatusCount(rawStatuses) {
    return rawStatuses
        .reduce((prev, cur) => {
          const oldPathStatus = cur.old_path_status;
          const newPathStatus = cur.new_path_status;
          if (newPathStatus && this._isMissing(newPathStatus.status)) {
            prev.missing ++;
          } else if (newPathStatus && this._isPending(newPathStatus.status)) {
            prev.pending ++;
          } else if (oldPathStatus) {
            // check oldPath if newPath approved or the file is deleted
            if (this._isMissing(oldPathStatus.status)) {
              prev.missing ++;
            } else if (this._isPending(oldPathStatus.status)) {
              prev.pending ++;
            }
          } else {
            prev.approved ++;
          }
          return prev;
        }, {missing: 0, pending: 0, approved: 0});
  }

  _computeStatusText(statusCount, isOverriden) {
    if (statusCount === undefined || isOverriden === undefined) return '';
    const statusText = [];
    if (statusCount.missing) {
      statusText.push(`${statusCount.missing} missing`);
    }

    if (statusCount.pending) {
      statusText.push(`${statusCount.pending} pending`);
    }

    if (!statusText.length) {
      statusText.push(isOverriden ? 'Approved (Owners-Override)' : 'Approved');
    }

    return statusText.join(', ');
  }

  _isMissing(status) {
    return status === OwnerStatus.INSUFFICIENT_REVIEWERS;
  }

  _isPending(status) {
    return status === OwnerStatus.PENDING;
  }

  _openReplyDialog() {
    this.model.setShowSuggestions(true);
    this.dispatchEvent(
        new CustomEvent('open-reply-dialog', {
          detail: {},
          composed: true,
          bubbles: true,
        })
    );
    this.reporting.reportInteraction('suggest-owners-from-submit-requirement',
        {user_role: this.model.userRole});
  }

  _showFailDetails() {
    showPluginFailedMessage(this, this.model.pluginStatus);
  }
}

customElements.define(OwnerRequirementValue.is, OwnerRequirementValue);
