/**
 * @license
 * Copyright (C) 2016 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 '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import '../../shared/gr-dropdown/gr-dropdown';
import '../../shared/gr-icons/gr-icons';
import '../../shared/gr-js-api-interface/gr-js-api-interface';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
import '../gr-account-dropdown/gr-account-dropdown';
import '../gr-smart-search/gr-smart-search';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-main-header_html';
import {getBaseUrl, getDocsBaseUrl} from '../../../utils/url-util';
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {getAdminLinks, NavLink} from '../../../utils/admin-nav-util';
import {customElement, property, observe} from '@polymer/decorators';
import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
import {
  AccountDetailInfo,
  RequireProperties,
  ServerInfo,
  TopMenuEntryInfo,
  TopMenuItemInfo,
} from '../../../types/common';
import {JsApiService} from '../../shared/gr-js-api-interface/gr-js-api-types';
import {AuthType} from '../../../constants/constants';
import {DropdownLink} from '../../shared/gr-dropdown/gr-dropdown';

type MainHeaderLink = RequireProperties<DropdownLink, 'url' | 'name'>;

interface MainHeaderLinkGroup {
  title: string;
  links: MainHeaderLink[];
  class?: string;
}

const DEFAULT_LINKS: MainHeaderLinkGroup[] = [
  {
    title: 'Changes',
    links: [
      {
        url: '/q/status:open+-is:wip',
        name: 'Open',
      },
      {
        url: '/q/status:merged',
        name: 'Merged',
      },
      {
        url: '/q/status:abandoned',
        name: 'Abandoned',
      },
    ],
  },
];

const DOCUMENTATION_LINKS: MainHeaderLink[] = [
  {
    url: '/index.html',
    name: 'Table of Contents',
  },
  {
    url: '/user-search.html',
    name: 'Searching',
  },
  {
    url: '/user-upload.html',
    name: 'Uploading',
  },
  {
    url: '/access-control.html',
    name: 'Access Control',
  },
  {
    url: '/rest-api.html',
    name: 'REST API',
  },
  {
    url: '/intro-project-owner.html',
    name: 'Project Owner Guide',
  },
];

// Set of authentication methods that can provide custom registration page.
const AUTH_TYPES_WITH_REGISTER_URL: Set<AuthType> = new Set([
  AuthType.LDAP,
  AuthType.LDAP_BIND,
  AuthType.CUSTOM_EXTENSION,
]);

export interface GrMainHeader {
  $: {
    restAPI: RestApiService & Element;
    jsAPI: JsApiService & Element;
  };
}

@customElement('gr-main-header')
export class GrMainHeader extends GestureEventListeners(
  LegacyElementMixin(PolymerElement)
) {
  static get template() {
    return htmlTemplate;
  }

  @property({type: String, notify: true})
  searchQuery?: string;

  @property({type: Boolean, reflectToAttribute: true})
  loggedIn?: boolean;

  @property({type: Boolean, reflectToAttribute: true})
  loading?: boolean;

  @property({type: Object})
  _account?: AccountDetailInfo;

  @property({type: Array})
  _adminLinks: NavLink[] = [];

  @property({type: String})
  _docBaseUrl: string | null = null;

  @property({
    type: Array,
    computed: '_computeLinks(_userLinks, _adminLinks, _topMenus, _docBaseUrl)',
  })
  _links?: MainHeaderLinkGroup[];

  @property({type: String})
  loginUrl = '/login';

  @property({type: Array})
  _userLinks: MainHeaderLink[] = [];

  @property({type: Array})
  _topMenus?: TopMenuEntryInfo[] = [];

  @property({type: String})
  _registerText = 'Sign up';

  // Empty string means that the register <div> will be hidden.
  @property({type: String})
  _registerURL = '';

  @property({type: Boolean})
  mobileSearchHidden = false;

  /** @override */
  ready() {
    super.ready();
    this._ensureAttribute('role', 'banner');
  }

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

  /** @override */
  detached() {
    super.detached();
  }

  reload() {
    this._loadAccount();
  }

  _computeRelativeURL(path: string) {
    return '//' + window.location.host + getBaseUrl() + path;
  }

  _computeLinks(
    userLinks?: TopMenuItemInfo[],
    adminLinks?: NavLink[],
    topMenus?: TopMenuEntryInfo[],
    docBaseUrl?: string | null,
    // defaultLinks parameter is used in tests only
    defaultLinks = DEFAULT_LINKS
  ) {
    // Polymer 2: check for undefined
    if (
      userLinks === undefined ||
      adminLinks === undefined ||
      topMenus === undefined ||
      docBaseUrl === undefined
    ) {
      return undefined;
    }

    const links: MainHeaderLinkGroup[] = defaultLinks.map(menu => {
      return {
        title: menu.title,
        links: menu.links.slice(),
      };
    });
    if (userLinks && userLinks.length > 0) {
      links.push({
        title: 'Your',
        links: userLinks.slice(),
      });
    }
    const docLinks = this._getDocLinks(docBaseUrl, DOCUMENTATION_LINKS);
    if (docLinks.length) {
      links.push({
        title: 'Documentation',
        links: docLinks,
        class: 'hideOnMobile',
      });
    }
    links.push({
      title: 'Browse',
      links: adminLinks.slice(),
    });
    const topMenuLinks: {[name: string]: MainHeaderLink[]} = {};
    links.forEach(link => {
      topMenuLinks[link.title] = link.links;
    });
    for (const m of topMenus) {
      const items = m.items.map(this._createHeaderLink).filter(
        link =>
          // Ignore GWT project links
          !link.url.includes('${projectName}')
      );
      if (m.name in topMenuLinks) {
        items.forEach(link => {
          topMenuLinks[m.name].push(link);
        });
      } else if (items.length > 0) {
        links.push({
          title: m.name,
          links: topMenuLinks[m.name] = items,
        });
      }
    }
    return links;
  }

  _getDocLinks(docBaseUrl: string | null, docLinks: MainHeaderLink[]) {
    if (!docBaseUrl) {
      return [];
    }
    return docLinks.map(link => {
      let url = docBaseUrl;
      if (url && url[url.length - 1] === '/') {
        url = url.substring(0, url.length - 1);
      }
      return {
        url: url + link.url,
        name: link.name,
        target: '_blank',
      };
    });
  }

  _loadAccount() {
    this.loading = true;

    return Promise.all([
      this.$.restAPI.getAccount(),
      this.$.restAPI.getTopMenus(),
      getPluginLoader().awaitPluginsLoaded(),
    ]).then(result => {
      const account = result[0];
      this._account = account;
      this.loggedIn = !!account;
      this.loading = false;
      this._topMenus = result[1];

      return getAdminLinks(
        account,
        () =>
          this.$.restAPI.getAccountCapabilities().then(capabilities => {
            if (!capabilities) {
              throw new Error('getAccountCapabilities returns undefined');
            }
            return capabilities;
          }),
        () => this.$.jsAPI.getAdminMenuLinks()
      ).then(res => {
        this._adminLinks = res.links;
      });
    });
  }

  _loadConfig() {
    this.$.restAPI
      .getConfig()
      .then(config => {
        if (!config) {
          throw new Error('getConfig returned undefined');
        }
        this._retrieveRegisterURL(config);
        return getDocsBaseUrl(config, this.$.restAPI);
      })
      .then(docBaseUrl => {
        this._docBaseUrl = docBaseUrl;
      });
  }

  @observe('_account')
  _accountLoaded(account?: AccountDetailInfo) {
    if (!account) {
      return;
    }

    this.$.restAPI.getPreferences().then(prefs => {
      this._userLinks =
        prefs && prefs.my ? prefs.my.map(this._createHeaderLink) : [];
    });
  }

  _retrieveRegisterURL(config: ServerInfo) {
    if (AUTH_TYPES_WITH_REGISTER_URL.has(config.auth.auth_type)) {
      this._registerURL = config.auth.register_url ?? '';
      if (config.auth.register_text) {
        this._registerText = config.auth.register_text;
      }
    }
  }

  _computeRegisterHidden(registerURL: string) {
    return !registerURL;
  }

  _createHeaderLink(linkObj: TopMenuItemInfo): MainHeaderLink {
    // Delete target property due to complications of
    // https://bugs.chromium.org/p/gerrit/issues/detail?id=5888
    //
    // The server tries to guess whether URL is a view within the UI.
    // If not, it sets target='_blank' on the menu item. The server
    // makes assumptions that work for the GWT UI, but not PolyGerrit,
    // so we'll just disable it altogether for now.
    const {target, ...headerLink} = {...linkObj};

    // Normalize all urls to PolyGerrit style.
    if (headerLink.url.startsWith('#')) {
      headerLink.url = linkObj.url.slice(1);
    }

    return headerLink;
  }

  _generateSettingsLink() {
    return getBaseUrl() + '/settings/';
  }

  _onMobileSearchTap(e: Event) {
    e.preventDefault();
    e.stopPropagation();
    this.dispatchEvent(
      new CustomEvent('mobile-search', {
        composed: true,
        bubbles: false,
      })
    );
  }

  _computeLinkGroupClass(linkGroup: MainHeaderLinkGroup) {
    return linkGroup.class ?? '';
  }

  _computeShowHideAriaLabel(mobileSearchHidden: boolean) {
    if (mobileSearchHidden) {
      return 'Show Searchbar';
    } else {
      return 'Hide Searchbar';
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-main-header': GrMainHeader;
  }
}
