/**
 * @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.
 */

export const SuggestionsState = {
  NotLoaded: 'NotLoaded',
  Loaded: 'Loaded',
  Loading: 'Loading',
  LoadFailed: 'LoadFailed',
};

export const PluginState = {
  Enabled: 'Enabled',
  Disabled: 'Disabled',
  ServerConfigurationError: 'ServerConfigurationError',
  Failed: 'Failed',
};

export function isPluginErrorState(state) {
  return state === PluginState.ServerConfigurationError ||
      state === PluginState.Failed;
}

export const SuggestionsType = {
  BEST_SUGGESTIONS: 'BEST_SUGGESTIONS',
  ALL_SUGGESTIONS: 'ALL_SUGGESTIONS',
};

/**
 * @enum
 */
export const UserRole = {
  ANONYMOUS: 'ANONYMOUS',
  AUTHOR: 'AUTHOR',
  CHANGE_OWNER: 'CHANGE_OWNER',
  REVIEWER: 'REVIEWER',
  CC: 'CC',
  REMOVED_REVIEWER: 'REMOVED_REVIEWER',
  OTHER: 'OTHER',
};

export const BestSuggestionsLimit = 5;
export const AllSuggestionsLimit = 1000;

/**
 * Maintain the state of code-owners.
 * Raises 'model-property-changed' event when a property is changed.
 * The plugin shares the same model between all UI elements (if it is not,
 * the plugin can't maintain showSuggestions state across different UI elements).
 * UI elements use values from this model to display information
 * and listens for the model-property-changed event. To do so, UI elements
 * add CodeOwnersModelMixin, which is doing the listening and the translation
 * from model-property-changed event to Polymer property-changed-event. The
 * translation allows to use model properties in observables, bindings,
 * computed properties, etc...
 * The CodeOwnersModelLoader updates the model.
 *
 * It would be good to use RxJs Observable for implementing model properties.
 * However, RxJs library is imported by Gerrit and there is no
 * good way to reuse the same library in the plugin.
 */
export class CodeOwnersModel extends EventTarget {
  constructor(change) {
    super();
    this.change = change;
    this.branchConfig = undefined;
    this.status = undefined;
    this.userRole = undefined;
    this.isCodeOwnerEnabled = undefined;
    this.areAllFilesApproved = undefined;
    this.suggestionsByTypes = {};
    for (const suggestionType of Object.values(SuggestionsType)) {
      this.suggestionsByTypes[suggestionType] = {
        files: undefined,
        state: SuggestionsState.NotLoaded,
        loadProgress: undefined,
      };
    }
    this.selectedSuggestionsType = SuggestionsType.BEST_SUGGESTIONS;
    this.showSuggestions = false;
    this.pluginStatus = undefined;
  }

  get selectedSuggestions() {
    return this.suggestionsByTypes[this.selectedSuggestionsType];
  }

  setBranchConfig(config) {
    if (this.branchConfig === config) return;
    this.branchConfig = config;
    this._firePropertyChanged('branchConfig');
  }

  setStatus(status) {
    if (this.status === status) return;
    this.status = status;
    this._firePropertyChanged('status');
  }

  setUserRole(userRole) {
    if (this.userRole === userRole) return;
    this.userRole = userRole;
    this._firePropertyChanged('userRole');
  }

  setIsCodeOwnerEnabled(enabled) {
    if (this.isCodeOwnerEnabled === enabled) return;
    this.isCodeOwnerEnabled = enabled;
    this._firePropertyChanged('isCodeOwnerEnabled');
  }

  setAreAllFilesApproved(approved) {
    if (this.areAllFilesApproved === approved) return;
    this.areAllFilesApproved = approved;
    this._firePropertyChanged('areAllFilesApproved');
  }

  setSuggestionsFiles(suggestionsType, files) {
    const suggestions = this.suggestionsByTypes[suggestionsType];
    if (suggestions.files === files) return;
    suggestions.files = files;
    this._fireSuggestionsChanged(suggestionsType, 'files');
  }

  setSuggestionsState(suggestionsType, state) {
    const suggestions = this.suggestionsByTypes[suggestionsType];
    if (suggestions.state === state) return;
    suggestions.state = state;
    this._fireSuggestionsChanged(suggestionsType, 'state');
  }

  setSuggestionsLoadProgress(suggestionsType, progress) {
    const suggestions = this.suggestionsByTypes[suggestionsType];
    if (suggestions.loadProgress === progress) return;
    suggestions.loadProgress = progress;
    this._fireSuggestionsChanged(suggestionsType, 'loadProgress');
  }

  setSelectedSuggestionType(suggestionsType) {
    if (this.selectedSuggestionsType === suggestionsType) return;
    this.selectedSuggestionsType = suggestionsType;
    this._firePropertyChanged('selectedSuggestionsType');
    this._firePropertyChanged('selectedSuggestions');
  }

  setShowSuggestions(show) {
    if (this.showSuggestions === show) return;
    this.showSuggestions = show;
    this._firePropertyChanged('showSuggestions');
  }

  setPluginEnabled(enabled) {
    this._setPluginStatus({state: enabled ?
      PluginState.Enabled : PluginState.Disabled});
  }

  setServerConfigurationError(failedMessage) {
    this._setPluginStatus({state: PluginState.ServerConfigurationError,
      failedMessage});
  }

  setPluginFailed(failedMessage) {
    this._setPluginStatus({state: PluginState.Failed, failedMessage});
  }

  _setPluginStatus(status) {
    if (this._arePluginStatusesEqual(this.pluginStatus, status)) return;
    this.pluginStatus = status;
    this._firePropertyChanged('pluginStatus');
  }

  _arePluginStatusesEqual(status1, status2) {
    if (status1 === undefined || status2 === undefined) {
      return status1 === status2;
    }
    if (status1.state !== status2.state) return false;
    return isPluginErrorState(status1.state)?
      status1.failedMessage === status2.failedMessage :
      true;
  }

  _firePropertyChanged(propertyName) {
    this.dispatchEvent(new CustomEvent('model-property-changed', {
      detail: {
        propertyName,
      },
    }));
  }

  _fireSuggestionsChanged(suggestionsType, propertyName) {
    this._firePropertyChanged(
        `suggestionsByTypes.${suggestionsType}.${propertyName}`);
    if (suggestionsType === this.selectedSuggestionsType) {
      this._firePropertyChanged(`selectedSuggestions.${propertyName}`);
    }
  }

  static getModel(change) {
    if (!this.model || this.model.change !== change) {
      this.model = new CodeOwnersModel(change);
    }
    return this.model;
  }
}
