/**
 * @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.
 */
(function() {
  'use strict';

  const STATES = {
    active: {value: 'ACTIVE', label: 'Active'},
    readOnly: {value: 'READ_ONLY', label: 'Read Only'},
    hidden: {value: 'HIDDEN', label: 'Hidden'},
  };

  const SUBMIT_TYPES = {
    // Exclude INHERIT, which is handled specially.
    mergeIfNecessary: {
      value: 'MERGE_IF_NECESSARY',
      label: 'Merge if necessary',
    },
    fastForwardOnly: {
      value: 'FAST_FORWARD_ONLY',
      label: 'Fast forward only',
    },
    rebaseAlways: {
      value: 'REBASE_ALWAYS',
      label: 'Rebase Always',
    },
    rebaseIfNecessary: {
      value: 'REBASE_IF_NECESSARY',
      label: 'Rebase if necessary',
    },
    mergeAlways: {
      value: 'MERGE_ALWAYS',
      label: 'Merge always',
    },
    cherryPick: {
      value: 'CHERRY_PICK',
      label: 'Cherry pick',
    },
  };

  /**
   * @appliesMixin Gerrit.FireMixin
   */
  class GrRepo extends Polymer.mixinBehaviors( [
    Gerrit.FireBehavior,
  ], Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element))) {
    static get is() { return 'gr-repo'; }

    static get properties() {
      return {
        params: Object,
        repo: String,

        _configChanged: {
          type: Boolean,
          value: false,
        },
        _loading: {
          type: Boolean,
          value: true,
        },
        _loggedIn: {
          type: Boolean,
          value: false,
          observer: '_loggedInChanged',
        },
        /** @type {?} */
        _repoConfig: Object,
        /** @type {?} */
        _pluginData: {
          type: Array,
          computed: '_computePluginData(_repoConfig.plugin_config.*)',
        },
        _readOnly: {
          type: Boolean,
          value: true,
        },
        _states: {
          type: Array,
          value() {
            return Object.values(STATES);
          },
        },
        _submitTypes: {
          type: Array,
          value() {
            return Object.values(SUBMIT_TYPES);
          },
        },
        _schemes: {
          type: Array,
          value() { return []; },
          computed: '_computeSchemes(_schemesObj)',
          observer: '_schemesChanged',
        },
        _selectedCommand: {
          type: String,
          value: 'Clone',
        },
        _selectedScheme: String,
        _schemesObj: Object,
      };
    }

    static get observers() {
      return [
        '_handleConfigChanged(_repoConfig.*)',
      ];
    }

    attached() {
      super.attached();
      this._loadRepo();

      this.fire('title-change', {title: this.repo});
    }

    _computePluginData(configRecord) {
      if (!configRecord ||
          !configRecord.base) { return []; }

      const pluginConfig = configRecord.base;
      return Object.keys(pluginConfig)
          .map(name => ({name, config: pluginConfig[name]}));
    }

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

      const promises = [];

      const errFn = response => {
        this.fire('page-error', {response});
      };

      promises.push(this._getLoggedIn().then(loggedIn => {
        this._loggedIn = loggedIn;
        if (loggedIn) {
          this.$.restAPI.getRepoAccess(this.repo).then(access => {
            if (!access) { return Promise.resolve(); }

            // If the user is not an owner, is_owner is not a property.
            this._readOnly = !access[this.repo].is_owner;
          });
        }
      }));

      promises.push(this.$.restAPI.getProjectConfig(this.repo, errFn)
          .then(config => {
            if (!config) { return Promise.resolve(); }

            if (config.default_submit_type) {
              // The gr-select is bound to submit_type, which needs to be the
              // *configured* submit type. When default_submit_type is
              // present, the server reports the *effective* submit type in
              // submit_type, so we need to overwrite it before storing the
              // config in this.
              config.submit_type =
                  config.default_submit_type.configured_value;
            }
            if (!config.state) {
              config.state = STATES.active.value;
            }
            this._repoConfig = config;
            this._loading = false;
          }));

      promises.push(this.$.restAPI.getConfig().then(config => {
        if (!config) { return Promise.resolve(); }

        this._schemesObj = config.download.schemes;
      }));

      return Promise.all(promises);
    }

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

    _computeHideClass(arr) {
      return !arr || !arr.length ? 'hide' : '';
    }

    _loggedInChanged(_loggedIn) {
      if (!_loggedIn) { return; }
      this.$.restAPI.getPreferences().then(prefs => {
        if (prefs.download_scheme) {
          // Note (issue 5180): normalize the download scheme with lower-case.
          this._selectedScheme = prefs.download_scheme.toLowerCase();
        }
      });
    }

    _formatBooleanSelect(item) {
      if (!item) { return; }
      let inheritLabel = 'Inherit';
      if (!(item.inherited_value === undefined)) {
        inheritLabel = `Inherit (${item.inherited_value})`;
      }
      return [
        {
          label: inheritLabel,
          value: 'INHERIT',
        },
        {
          label: 'True',
          value: 'TRUE',
        }, {
          label: 'False',
          value: 'FALSE',
        },
      ];
    }

    _formatSubmitTypeSelect(projectConfig) {
      if (!projectConfig) { return; }
      const allValues = Object.values(SUBMIT_TYPES);
      const type = projectConfig.default_submit_type;
      if (!type) {
        // Server is too old to report default_submit_type, so assume INHERIT
        // is not a valid value.
        return allValues;
      }

      let inheritLabel = 'Inherit';
      if (type.inherited_value) {
        let inherited = type.inherited_value;
        for (const val of allValues) {
          if (val.value === type.inherited_value) {
            inherited = val.label;
            break;
          }
        }
        inheritLabel = `Inherit (${inherited})`;
      }
      return [
        {
          label: inheritLabel,
          value: 'INHERIT',
        },
        ...allValues,
      ];
    }

    _isLoading() {
      return this._loading || this._loading === undefined;
    }

    _getLoggedIn() {
      return this.$.restAPI.getLoggedIn();
    }

    _formatRepoConfigForSave(repoConfig) {
      const configInputObj = {};
      for (const key in repoConfig) {
        if (repoConfig.hasOwnProperty(key)) {
          if (key === 'default_submit_type') {
            // default_submit_type is not in the input type, and the
            // configured value was already copied to submit_type by
            // _loadProject. Omit this property when saving.
            continue;
          }
          if (key === 'plugin_config') {
            configInputObj.plugin_config_values = repoConfig[key];
          } else if (typeof repoConfig[key] === 'object') {
            configInputObj[key] = repoConfig[key].configured_value;
          } else {
            configInputObj[key] = repoConfig[key];
          }
        }
      }
      return configInputObj;
    }

    _handleSaveRepoConfig() {
      return this.$.restAPI.saveRepoConfig(this.repo,
          this._formatRepoConfigForSave(this._repoConfig)).then(() => {
        this._configChanged = false;
      });
    }

    _handleConfigChanged() {
      if (this._isLoading()) { return; }
      this._configChanged = true;
    }

    _computeButtonDisabled(readOnly, configChanged) {
      return readOnly || !configChanged;
    }

    _computeHeaderClass(configChanged) {
      return configChanged ? 'edited' : '';
    }

    _computeSchemes(schemesObj) {
      return Object.keys(schemesObj);
    }

    _schemesChanged(schemes) {
      if (schemes.length === 0) { return; }
      if (!schemes.includes(this._selectedScheme)) {
        this._selectedScheme = schemes.sort()[0];
      }
    }

    _computeCommands(repo, schemesObj, _selectedScheme) {
      if (!schemesObj || !repo || !_selectedScheme) {
        return [];
      }
      const commands = [];
      let commandObj;
      if (schemesObj.hasOwnProperty(_selectedScheme)) {
        commandObj = schemesObj[_selectedScheme].clone_commands;
      }
      for (const title in commandObj) {
        if (!commandObj.hasOwnProperty(title)) { continue; }
        commands.push({
          title,
          command: commandObj[title]
              .replace(/\$\{project\}/gi, encodeURI(repo))
              .replace(/\$\{project-base-name\}/gi,
                  encodeURI(repo.substring(repo.lastIndexOf('/') + 1))),
        });
      }
      return commands;
    }

    _computeRepositoriesClass(config) {
      return config ? 'showConfig': '';
    }

    _computeChangesUrl(name) {
      return Gerrit.Nav.getUrlForProjectChanges(name);
    }

    _handlePluginConfigChanged({detail: {name, config, notifyPath}}) {
      this._repoConfig.plugin_config[name] = config;
      this.notifyPath('_repoConfig.plugin_config.' + notifyPath);
    }
  }

  customElements.define(GrRepo.is, GrRepo);
})();
