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

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

      ownerService: Object,

      _statusCount: Object,
      _isLoading: {
        type: Boolean,
        value: true,
      },
      _allApproved: {
        type: Boolean,
        computed: '_computeAllApproved(_statusCount)',
      },
      _isOverriden: Boolean,
      _overrideInfoUrl: String,
    };
  }

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

  _checkIfOverriden() {
    this.ownerService.getProjectConfig().then(res => {
      if (!res['override_approval']) {
        // no override label configured
        this._isOverriden = false;
        return;
      }

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

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

      // otherwise always reset it to false
      this._isOverriden = false;
    });
  }

  _updateStatus() {
    this._isLoading = true;
    this.reporting.reportLifeCycle('owners-submit-requirement-summary-start');

    return this.ownerService.getStatus()
        .then(({rawStatuses}) => {
          this._statusCount = this._getStatusCount(rawStatuses);
          this.ownerService.getLoggedInUserInitialRole().then(role => {
            // Send a metric with overall summary when code owners submit
            // requirement shown and finished fetching status
            this.reporting.reportLifeCycle(
                'owners-submit-requirement-summary-shown',
                {...this._statusCount, user_role: role}
            );
          });
        })
        .finally(() => {
          this._isLoading = false;
        });
  }

  _updateOverrideInfoUrl() {
    this.ownerService.getProjectConfig().then(config => {
      this._overrideInfoUrl = config.general && config.general.override_info_url
        ?
        config.general.override_info_url : '';
    });
  }

  _computeAllApproved(statusCount) {
    return 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 (this._isMissing(newPathStatus.status)) {
            prev.missing ++;
          } else if (this._isPending(newPathStatus.status)) {
            prev.pending ++;
          } else if (oldPathStatus) {
            // check oldPath if newPath approved
            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) {
    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;
  }

  onInputChanged(restApi, change, reporting) {
    if ([restApi, change, reporting].includes(undefined)) return;
    this.ownerService = CodeOwnerService.getOwnerService(this.restApi, change);
    this._updateStatus();
    this._checkIfOverriden();
    this._updateOverrideInfoUrl();
  }

  _openReplyDialog() {
    this.dispatchEvent(
        new CustomEvent('open-reply-dialog', {
          detail: {},
          composed: true,
          bubbles: true,
        })
    );
    ownerState.expandSuggestion = true;
    this.ownerService.getLoggedInUserInitialRole().then(role => {
      this.reporting.reportInteraction(
          'suggest-owners-from-submit-requirement', {user_role: role});
    });
  }
}

customElements.define(OwnerRequirementValue.is, OwnerRequirementValue);
