/**
 * @license
 * Copyright (C) 2017 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 '../../../scripts/bundled-polymer.js';
import '../../../styles/gr-menu-page-styles.js';
import '../../../styles/gr-page-nav-styles.js';
import '../../../styles/shared-styles.js';
import '../../shared/gr-dropdown-list/gr-dropdown-list.js';
import '../../shared/gr-icons/gr-icons.js';
import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
import '../../shared/gr-page-nav/gr-page-nav.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-admin-group-list/gr-admin-group-list.js';
import '../gr-group/gr-group.js';
import '../gr-group-audit-log/gr-group-audit-log.js';
import '../gr-group-members/gr-group-members.js';
import '../gr-plugin-list/gr-plugin-list.js';
import '../gr-repo/gr-repo.js';
import '../gr-repo-access/gr-repo-access.js';
import '../gr-repo-commands/gr-repo-commands.js';
import '../gr-repo-dashboards/gr-repo-dashboards.js';
import '../gr-repo-detail-list/gr-repo-detail-list.js';
import '../gr-repo-list/gr-repo-list.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-admin-view_html.js';
import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
import {AdminNavBehavior} from '../../../behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior.js';
import {URLEncodingBehavior} from '../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';

const INTERNAL_GROUP_REGEX = /^[\da-f]{40}$/;

/**
 * @extends Polymer.Element
 */
class GrAdminView extends mixinBehaviors( [
  AdminNavBehavior,
  BaseUrlBehavior,
  URLEncodingBehavior,
], GestureEventListeners(
    LegacyElementMixin(
        PolymerElement))) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-admin-view'; }

  static get properties() {
    return {
    /** @type {?} */
      params: Object,
      path: String,
      adminView: String,

      _breadcrumbParentName: String,
      _repoName: String,
      _groupId: {
        type: Number,
        observer: '_computeGroupName',
      },
      _groupIsInternal: Boolean,
      _groupName: String,
      _groupOwner: {
        type: Boolean,
        value: false,
      },
      _subsectionLinks: Array,
      _filteredLinks: Array,
      _showDownload: {
        type: Boolean,
        value: false,
      },
      _isAdmin: {
        type: Boolean,
        value: false,
      },
      _showGroup: Boolean,
      _showGroupAuditLog: Boolean,
      _showGroupList: Boolean,
      _showGroupMembers: Boolean,
      _showRepoAccess: Boolean,
      _showRepoCommands: Boolean,
      _showRepoDashboards: Boolean,
      _showRepoDetailList: Boolean,
      _showRepoMain: Boolean,
      _showRepoList: Boolean,
      _showPluginList: Boolean,
    };
  }

  static get observers() {
    return [
      '_paramsChanged(params)',
    ];
  }

  /** @override */
  attached() {
    super.attached();
    this.reload();
  }

  reload() {
    const promises = [
      this.$.restAPI.getAccount(),
      pluginLoader.awaitPluginsLoaded(),
    ];
    return Promise.all(promises).then(result => {
      this._account = result[0];
      let options;
      if (this._repoName) {
        options = {repoName: this._repoName};
      } else if (this._groupId) {
        options = {
          groupId: this._groupId,
          groupName: this._groupName,
          groupIsInternal: this._groupIsInternal,
          isAdmin: this._isAdmin,
          groupOwner: this._groupOwner,
        };
      }

      return this.getAdminLinks(this._account,
          this.$.restAPI.getAccountCapabilities.bind(this.$.restAPI),
          this.$.jsAPI.getAdminMenuLinks.bind(this.$.jsAPI),
          options)
          .then(res => {
            this._filteredLinks = res.links;
            this._breadcrumbParentName = res.expandedSection ?
              res.expandedSection.name : '';

            if (!res.expandedSection) {
              this._subsectionLinks = [];
              return;
            }
            this._subsectionLinks = [res.expandedSection]
                .concat(res.expandedSection.children).map(section => {
                  return {
                    text: !section.detailType ? 'Home' : section.name,
                    value: section.view + (section.detailType || ''),
                    view: section.view,
                    url: section.url,
                    detailType: section.detailType,
                    parent: this._groupId || this._repoName || '',
                  };
                });
          });
    });
  }

  _computeSelectValue(params) {
    if (!params || !params.view) { return; }
    return params.view + (params.detail || '');
  }

  _selectedIsCurrentPage(selected) {
    return (selected.parent === (this._repoName || this._groupId) &&
        selected.view === this.params.view &&
        selected.detailType === this.params.detail);
  }

  _handleSubsectionChange(e) {
    const selected = this._subsectionLinks
        .find(section => section.value === e.detail.value);

    // This is when it gets set initially.
    if (this._selectedIsCurrentPage(selected)) {
      return;
    }
    GerritNav.navigateToRelativeUrl(selected.url);
  }

  _paramsChanged(params) {
    const isGroupView = params.view === GerritNav.View.GROUP;
    const isRepoView = params.view === GerritNav.View.REPO;
    const isAdminView = params.view === GerritNav.View.ADMIN;

    this.set('_showGroup', isGroupView && !params.detail);
    this.set('_showGroupAuditLog', isGroupView &&
        params.detail === GerritNav.GroupDetailView.LOG);
    this.set('_showGroupMembers', isGroupView &&
        params.detail === GerritNav.GroupDetailView.MEMBERS);

    this.set('_showGroupList', isAdminView &&
        params.adminView === 'gr-admin-group-list');

    this.set('_showRepoAccess', isRepoView &&
        params.detail === GerritNav.RepoDetailView.ACCESS);
    this.set('_showRepoCommands', isRepoView &&
        params.detail === GerritNav.RepoDetailView.COMMANDS);
    this.set('_showRepoDetailList', isRepoView &&
        (params.detail === GerritNav.RepoDetailView.BRANCHES ||
         params.detail === GerritNav.RepoDetailView.TAGS));
    this.set('_showRepoDashboards', isRepoView &&
        params.detail === GerritNav.RepoDetailView.DASHBOARDS);
    this.set('_showRepoMain', isRepoView && !params.detail);

    this.set('_showRepoList', isAdminView &&
        params.adminView === 'gr-repo-list');

    this.set('_showPluginList', isAdminView &&
        params.adminView === 'gr-plugin-list');

    let needsReload = false;
    if (params.repo !== this._repoName) {
      this._repoName = params.repo || '';
      // Reloads the admin menu.
      needsReload = true;
    }
    if (params.groupId !== this._groupId) {
      this._groupId = params.groupId || '';
      // Reloads the admin menu.
      needsReload = true;
    }
    if (this._breadcrumbParentName && !params.groupId && !params.repo) {
      needsReload = true;
    }
    if (!needsReload) { return; }
    this.reload();
  }

  // TODO (beckysiegel): Update these functions after router abstraction is
  // updated. They are currently copied from gr-dropdown (and should be
  // updated there as well once complete).
  _computeURLHelper(host, path) {
    return '//' + host + this.getBaseUrl() + path;
  }

  _computeRelativeURL(path) {
    const host = window.location.host;
    return this._computeURLHelper(host, path);
  }

  _computeLinkURL(link) {
    if (!link || typeof link.url === 'undefined') { return ''; }
    if (link.target || !link.noBaseUrl) {
      return link.url;
    }
    return this._computeRelativeURL(link.url);
  }

  /**
   * @param {string} itemView
   * @param {Object} params
   * @param {string=} opt_detailType
   */
  _computeSelectedClass(itemView, params, opt_detailType) {
    if (!params) return '';
    // Group params are structured differently from admin params. Compute
    // selected differently for groups.
    // TODO(wyatta): Simplify this when all routes work like group params.
    if (params.view === GerritNav.View.GROUP &&
        itemView === GerritNav.View.GROUP) {
      if (!params.detail && !opt_detailType) { return 'selected'; }
      if (params.detail === opt_detailType) { return 'selected'; }
      return '';
    }

    if (params.view === GerritNav.View.REPO &&
        itemView === GerritNav.View.REPO) {
      if (!params.detail && !opt_detailType) { return 'selected'; }
      if (params.detail === opt_detailType) { return 'selected'; }
      return '';
    }

    if (params.detailType && params.detailType !== opt_detailType) {
      return '';
    }
    return itemView === params.adminView ? 'selected' : '';
  }

  _computeGroupName(groupId) {
    if (!groupId) { return ''; }

    const promises = [];
    this.$.restAPI.getGroupConfig(groupId).then(group => {
      if (!group || !group.name) { return; }

      this._groupName = group.name;
      this._groupIsInternal = !!group.id.match(INTERNAL_GROUP_REGEX);
      this.reload();

      promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
        this._isAdmin = isAdmin;
      }));

      promises.push(this.$.restAPI.getIsGroupOwner(group.name).then(
          isOwner => {
            this._groupOwner = isOwner;
          }));

      return Promise.all(promises).then(() => {
        this.reload();
      });
    });
  }

  _updateGroupName(e) {
    this._groupName = e.detail.name;
    this.reload();
  }
}

customElements.define(GrAdminView.is, GrAdminView);
