/**
 * @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-service.js';
import {CodeOwnersModelMixin} from './code-owners-model-mixin.js';
import {showPluginFailedMessage} from './code-owners-banner.js';
import {PluginState} 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]]">              
              <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="[[!_allApproved]]">
                <gr-button link on-click="_openReplyDialog">
                Suggest owners
              </gr-button>
              </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/+/master/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,
      _isLoading: {
        type: Boolean,
        computed: '_computeIsLoading(model.branchConfig, model.status, '
            + 'model.userRole, model.pluginStatus)',
      },
      _allApproved: {
        type: Boolean,
        computed: '_computeAllApproved(_statusCount)',
      },
      _isOverriden: {
        type: Boolean,
        computed: '_computeIsOverriden(model.branchConfig)',
      },
      _overrideInfoUrl: {
        type: String,
        computed: '_computeOverrideInfoUrl(model.branchConfig)',
      },
    };
  }

  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;
  }

  _pluginFailed(pluginStatus) {
    return pluginStatus && pluginStatus.state === PluginState.Failed;
  }

  _onStatusChanged(status, userRole) {
    if (!status || !userRole) {
      this._statusCount = undefined;
      return;
    }
    const rawStatuses = status.rawStatuses;
    this._statusCount = this._getStatusCount(rawStatuses);
    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(branchConfig) {
    if (!branchConfig || !branchConfig['override_approval']) {
      // no override label configured
      return false;
    }

    const overridenLabel = branchConfig['override_approval'].label;
    const overridenValue = branchConfig['override_approval'].value;

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

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

  _computeAllApproved(statusCount) {
    return statusCount && statusCount.missing === 0
            && statusCount.pending === 0;
  }

  _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);
