/**
 * @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 '../../../styles/gr-menu-page-styles';
import '../../../styles/gr-subpage-styles';
import '../../../styles/shared-styles';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
import '../gr-access-section/gr-access-section';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom';
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-repo-access_html';
import {encodeURL, getBaseUrl, singleDecodeURL} from '../../../utils/url-util';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {toSortedPermissionsArray} from '../../../utils/access-util';
import {customElement, property} from '@polymer/decorators';
import {
  RepoName,
  ProjectInfo,
  CapabilityInfoMap,
  LabelNameToLabelTypeInfoMap,
  ProjectAccessInput,
  GitRef,
  UrlEncodedRepoName,
  ProjectAccessGroups,
} from '../../../types/common';
import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
import {hasOwnProperty} from '../../../utils/common-util';
import {GrButton} from '../../shared/gr-button/gr-button';
import {GrAccessSection} from '../gr-access-section/gr-access-section';
import {
  AutocompleteQuery,
  AutocompleteSuggestion,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {
  EditableLocalAccessSectionInfo,
  PermissionAccessSection,
  PropertyTreeNode,
  PrimitiveValue,
} from './gr-repo-access-interfaces';

const NOTHING_TO_SAVE = 'No changes to save.';

const MAX_AUTOCOMPLETE_RESULTS = 50;

export interface GrRepoAccess {
  $: {
    restAPI: RestApiService & Element;
  };
}

/**
 * Fired when save is a no-op
 *
 * @event show-alert
 */
@customElement('gr-repo-access')
export class GrRepoAccess extends GestureEventListeners(
  LegacyElementMixin(PolymerElement)
) {
  static get template() {
    return htmlTemplate;
  }

  @property({type: String, observer: '_repoChanged'})
  repo?: RepoName;

  @property({type: String})
  path?: string;

  @property({type: Boolean})
  _canUpload?: boolean = false; // restAPI can return undefined

  @property({type: String})
  _inheritFromFilter?: RepoName;

  @property({type: Object})
  _query: AutocompleteQuery;

  @property({type: Array})
  _ownerOf?: GitRef[];

  @property({type: Object})
  _capabilities?: CapabilityInfoMap;

  @property({type: Object})
  _groups?: ProjectAccessGroups;

  @property({type: Object})
  _inheritsFrom?: ProjectInfo | null | {};

  @property({type: Object})
  _labels?: LabelNameToLabelTypeInfoMap;

  @property({type: Object})
  _local?: EditableLocalAccessSectionInfo;

  @property({type: Boolean, observer: '_handleEditingChanged'})
  _editing = false;

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

  @property({type: Array})
  _sections?: PermissionAccessSection[];

  @property({type: Array})
  _weblinks?: string[];

  @property({type: Boolean})
  _loading = true;

  private _originalInheritsFrom?: ProjectInfo | null;

  constructor() {
    super();
    this._query = () => this._getInheritFromSuggestions();
  }

  /** @override */
  created() {
    super.created();
    this.addEventListener('access-modified', () =>
      this._handleAccessModified()
    );
  }

  _handleAccessModified() {
    this._modified = true;
  }

  _repoChanged(repo: RepoName) {
    this._loading = true;

    if (!repo) {
      return Promise.resolve();
    }

    return this._reload(repo);
  }

  _reload(repo: RepoName) {
    const errFn = (response?: Response | null) => {
      this.dispatchEvent(
        new CustomEvent('page-error', {
          detail: {response},
          composed: true,
          bubbles: true,
        })
      );
    };

    this._editing = false;

    // Always reset sections when a project changes.
    this._sections = [];
    const sectionsPromises = this.$.restAPI
      .getRepoAccessRights(repo, errFn)
      .then(res => {
        if (!res) {
          return Promise.resolve(undefined);
        }

        // Keep a copy of the original inherit from values separate from
        // the ones data bound to gr-autocomplete, so the original value
        // can be restored if the user cancels.
        this._inheritsFrom = res.inherits_from
          ? {
              ...res.inherits_from,
            }
          : null;
        this._originalInheritsFrom = res.inherits_from
          ? {
              ...res.inherits_from,
            }
          : null;
        // Initialize the filter value so when the user clicks edit, the
        // current value appears. If there is no parent repo, it is
        // initialized as an empty string.
        this._inheritFromFilter = res.inherits_from
          ? res.inherits_from.name
          : ('' as RepoName);
        // 'as EditableLocalAccessSectionInfo' is required because res.local
        // type doesn't have index signature
        this._local = res.local as EditableLocalAccessSectionInfo;
        this._groups = res.groups;
        this._weblinks = res.config_web_links || [];
        this._canUpload = res.can_upload;
        this._ownerOf = res.owner_of || [];
        return toSortedPermissionsArray(this._local);
      });

    const capabilitiesPromises = this.$.restAPI
      .getCapabilities(errFn)
      .then(res => {
        if (!res) {
          return Promise.resolve(undefined);
        }

        return res;
      });

    const labelsPromises = this.$.restAPI.getRepo(repo, errFn).then(res => {
      if (!res) {
        return Promise.resolve(undefined);
      }

      return res.labels;
    });

    return Promise.all([
      sectionsPromises,
      capabilitiesPromises,
      labelsPromises,
    ]).then(([sections, capabilities, labels]) => {
      this._capabilities = capabilities;
      this._labels = labels;
      this._sections = sections;
      this._loading = false;
    });
  }

  _handleUpdateInheritFrom(e: CustomEvent<{value: string}>) {
    const parentProject: ProjectInfo = {
      id: e.detail.value as UrlEncodedRepoName,
      name: this._inheritFromFilter,
    };
    if (!this._inheritsFrom) {
      this._inheritsFrom = parentProject;
    } else {
      // TODO(TS): replace with
      // this._inheritsFrom = {...this._inheritsFrom, ...parentProject};
      const projectInfo = this._inheritsFrom as ProjectInfo;
      projectInfo.id = parentProject.id;
      projectInfo.name = parentProject.name;
    }
    this._handleAccessModified();
  }

  _getInheritFromSuggestions(): Promise<AutocompleteSuggestion[]> {
    return this.$.restAPI
      .getRepos(this._inheritFromFilter, MAX_AUTOCOMPLETE_RESULTS)
      .then(response => {
        const projects: AutocompleteSuggestion[] = [];
        if (!response) {
          return projects;
        }
        for (const item of response) {
          projects.push({
            name: item.name,
            value: item.id,
          });
        }
        return projects;
      });
  }

  _computeLoadingClass(loading: boolean) {
    return loading ? 'loading' : '';
  }

  _handleEdit() {
    this._editing = !this._editing;
  }

  _editOrCancel(editing: boolean) {
    return editing ? 'Cancel' : 'Edit';
  }

  _computeWebLinkClass(weblinks?: string[]) {
    return weblinks && weblinks.length ? 'show' : '';
  }

  _computeShowInherit(inheritsFrom?: RepoName) {
    return inheritsFrom ? 'show' : '';
  }

  // TODO(TS): Unclear what is model here, provide a better explanation
  _handleAddedSectionRemoved(e: CustomEvent & {model: {index: string}}) {
    if (!this._sections) {
      return;
    }
    const index = Number(e.model.index);
    if (isNaN(index)) {
      return;
    }
    this._sections = this._sections
      .slice(0, index)
      .concat(this._sections.slice(index + 1, this._sections.length));
  }

  _handleEditingChanged(editing: boolean, editingOld: boolean) {
    // Ignore when editing gets set initially.
    if (!editingOld || editing) {
      return;
    }
    // Remove any unsaved but added refs.
    if (this._sections) {
      this._sections = this._sections.filter(p => !p.value.added);
    }
    // Restore inheritFrom.
    if (this._inheritsFrom) {
      this._inheritsFrom = {...this._originalInheritsFrom};
      this._inheritFromFilter =
        'name' in this._inheritsFrom ? this._inheritsFrom.name : undefined;
    }
    if (!this._local) {
      return;
    }
    for (const key of Object.keys(this._local)) {
      if (this._local[key].added) {
        delete this._local[key];
      }
    }
  }

  _updateRemoveObj(addRemoveObj: {remove: PropertyTreeNode}, path: string[]) {
    let curPos: PropertyTreeNode = addRemoveObj.remove;
    for (const item of path) {
      if (!curPos[item]) {
        if (item === path[path.length - 1]) {
          if (path[path.length - 2] === 'permissions') {
            curPos[item] = {rules: {}};
          } else if (path.length === 1) {
            curPos[item] = {permissions: {}};
          } else {
            curPos[item] = {};
          }
        } else {
          curPos[item] = {};
        }
      }
      // The last item can be a PrimitiveValue, but we don't use it
      // All intermediate items are PropertyTreeNode
      // TODO(TS): rewrite this loop and process the last item explicitly
      curPos = curPos[item] as PropertyTreeNode;
    }
    return addRemoveObj;
  }

  _updateAddObj(
    addRemoveObj: {add: PropertyTreeNode},
    path: string[],
    value: PropertyTreeNode | PrimitiveValue
  ) {
    let curPos: PropertyTreeNode = addRemoveObj.add;
    for (const item of path) {
      if (!curPos[item]) {
        if (item === path[path.length - 1]) {
          curPos[item] = value;
        } else {
          curPos[item] = {};
        }
      }
      // The last item can be a PrimitiveValue, but we don't use it
      // All intermediate items are PropertyTreeNode
      // TODO(TS): rewrite this loop and process the last item explicitly
      curPos = curPos[item] as PropertyTreeNode;
    }
    return addRemoveObj;
  }

  /**
   * Used to recursively remove any objects with a 'deleted' bit.
   */
  _recursivelyRemoveDeleted(obj: PropertyTreeNode) {
    for (const k in obj) {
      if (!hasOwnProperty(obj, k)) {
        continue;
      }
      const node = obj[k];
      if (typeof node === 'object') {
        if (node.deleted) {
          delete obj[k];
          return;
        }
        this._recursivelyRemoveDeleted(node);
      }
    }
  }

  _recursivelyUpdateAddRemoveObj(
    obj: PropertyTreeNode,
    addRemoveObj: {
      add: PropertyTreeNode;
      remove: PropertyTreeNode;
    },
    path: string[] = []
  ) {
    for (const k in obj) {
      if (!hasOwnProperty(obj, k)) {
        continue;
      }
      const node = obj[k];
      if (typeof node === 'object') {
        const updatedId = node.updatedId;
        const ref = updatedId ? updatedId : k;
        if (node.deleted) {
          this._updateRemoveObj(addRemoveObj, path.concat(k));
          continue;
        } else if (node.modified) {
          this._updateRemoveObj(addRemoveObj, path.concat(k));
          this._updateAddObj(addRemoveObj, path.concat(ref), node);
          /* Special case for ref changes because they need to be added and
           removed in a different way. The new ref needs to include all
           changes but also the initial state. To do this, instead of
           continuing with the same recursion, just remove anything that is
           deleted in the current state. */
          if (updatedId && updatedId !== k) {
            this._recursivelyRemoveDeleted(
              addRemoveObj.add[updatedId] as PropertyTreeNode
            );
          }
          continue;
        } else if (node.added) {
          this._updateAddObj(addRemoveObj, path.concat(ref), node);
          /**
           * As add / delete both can happen in the new section,
           * so here to make sure it will remove the deleted ones.
           *
           * @see Issue 11339
           */
          this._recursivelyRemoveDeleted(
            addRemoveObj.add[k] as PropertyTreeNode
          );
          continue;
        }
        this._recursivelyUpdateAddRemoveObj(node, addRemoveObj, path.concat(k));
      }
    }
  }

  /**
   * Returns an object formatted for saving or submitting access changes for
   * review
   */
  _computeAddAndRemove() {
    const addRemoveObj: {
      add: PropertyTreeNode;
      remove: PropertyTreeNode;
      parent?: string | null;
    } = {
      add: {},
      remove: {},
    };

    const originalInheritsFromId = this._originalInheritsFrom
      ? singleDecodeURL(this._originalInheritsFrom.id)
      : null;
    // TODO(TS): this._inheritsFrom as ProjectInfo might be a mistake.
    // _inheritsFrom can be {}
    const inheritsFromId = this._inheritsFrom
      ? singleDecodeURL((this._inheritsFrom as ProjectInfo).id)
      : null;

    const inheritFromChanged =
      // Inherit from changed
      (originalInheritsFromId && originalInheritsFromId !== inheritsFromId) ||
      // Inherit from added (did not have one initially);
      (!originalInheritsFromId && inheritsFromId);

    if (!this._local) {
      return addRemoveObj;
    }

    this._recursivelyUpdateAddRemoveObj(
      (this._local as unknown) as PropertyTreeNode,
      addRemoveObj
    );

    if (inheritFromChanged) {
      addRemoveObj.parent = inheritsFromId;
    }
    return addRemoveObj;
  }

  _handleCreateSection() {
    if (!this._local) {
      return;
    }
    let newRef = 'refs/for/*';
    // Avoid using an already used key for the placeholder, since it
    // immediately gets added to an object.
    while (this._local[newRef]) {
      newRef = `${newRef}*`;
    }
    const section = {permissions: {}, added: true};
    this.push('_sections', {id: newRef, value: section});
    this.set(['_local', newRef], section);
    flush();
    // Template already instantiated at this point
    (this.root!.querySelector(
      'gr-access-section:last-of-type'
    ) as GrAccessSection).editReference();
  }

  _getObjforSave(): ProjectAccessInput | undefined {
    const addRemoveObj = this._computeAddAndRemove();
    // If there are no changes, don't actually save.
    if (
      !Object.keys(addRemoveObj.add).length &&
      !Object.keys(addRemoveObj.remove).length &&
      !addRemoveObj.parent
    ) {
      this.dispatchEvent(
        new CustomEvent('show-alert', {
          detail: {message: NOTHING_TO_SAVE},
          bubbles: true,
          composed: true,
        })
      );
      return;
    }
    const obj: ProjectAccessInput = ({
      add: addRemoveObj.add,
      remove: addRemoveObj.remove,
    } as unknown) as ProjectAccessInput;
    if (addRemoveObj.parent) {
      obj.parent = addRemoveObj.parent;
    }
    return obj;
  }

  _handleSave(e: Event) {
    const obj = this._getObjforSave();
    if (!obj) {
      return;
    }
    const button = e && (e.target as GrButton);
    if (button) {
      button.loading = true;
    }
    const repo = this.repo;
    if (!repo) {
      return Promise.resolve();
    }
    return this.$.restAPI
      .setRepoAccessRights(repo, obj)
      .then(() => {
        this._reload(repo);
      })
      .finally(() => {
        this._modified = false;
        if (button) {
          button.loading = false;
        }
      });
  }

  _handleSaveForReview(e: Event) {
    const obj = this._getObjforSave();
    if (!obj) {
      return;
    }
    const button = e && (e.target as GrButton);
    if (button) {
      button.loading = true;
    }
    if (!this.repo) {
      return;
    }
    return this.$.restAPI
      .setRepoAccessRightsForReview(this.repo, obj)
      .then(change => {
        GerritNav.navigateToChange(change);
      })
      .finally(() => {
        this._modified = false;
        if (button) {
          button.loading = false;
        }
      });
  }

  _computeSaveReviewBtnClass(canUpload?: boolean) {
    return !canUpload ? 'invisible' : '';
  }

  _computeSaveBtnClass(ownerOf?: GitRef[]) {
    return ownerOf && ownerOf.length === 0 ? 'invisible' : '';
  }

  _computeMainClass(
    ownerOf: GitRef[] | undefined,
    canUpload: boolean,
    editing: boolean
  ) {
    const classList = [];
    if ((ownerOf && ownerOf.length > 0) || canUpload) {
      classList.push('admin');
    }
    if (editing) {
      classList.push('editing');
    }
    return classList.join(' ');
  }

  _computeParentHref(repoName: RepoName) {
    return getBaseUrl() + `/admin/repos/${encodeURL(repoName, true)},access`;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-repo-access': GrRepoAccess;
  }
}
