/**
 * @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);
        }
        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);
