"use strict";

/**
 * Licensed Materials - Property of IBM
 * IBM Cognos Products: admin
 * Copyright IBM Corp. 2015, 2019
 * US Government Users Restricted Rights - Use, duplication or disclosure
 * restricted by GSA ADP Schedule Contract with IBM Corp.
 */
define(['underscore', 'bi/content_apps/PropertiesPageView', 'bi/admin/datasource/services/ApiSvc', 'bi/admin/datasource/services/DataSourceListController', 'bi/admin/multitenancy/services/TenantsCustomizationService', 'bi/admin/nls/StringResource', 'text!bi/admin/common/propertiespageview.json', 'bi/admin/common/utils/AJAXUtils', 'bi/admin/datasource/services/ConnectionUtils', 'bi/admin/datasource/services/ConnectionListController', 'bacontentnav/utils/UIHelper', '../ba-graphics/dist/icons-js/custom-visual_16', '../ba-graphics/dist/icons-js/schematic_16', 'bi/admin/common/services/ApiBase', 'jquery'], function (_, BasePropertiesPageView, datasourceApi, DataSourceListController, TenantsController, StringResource, propertiesPageViewDefinitions, AJAXUtils, ConnectionUtils, ConnectionListController, UIHelper, bundleTypeRendererIcon, bundleTypeSchematicIcon, ApiBase, $) {
  'use strict'; //NOSONAR: meant to be strict

  var PropertiesPageView = BasePropertiesPageView.extend({
    _objectIcons: {
      dataSource: {
        icon: '#common-data_source',
        tooltip: 'datasource'
      },
      dataSourceConnection: {
        icon: '#common-connection',
        tooltip: 'connection'
      },
      dataSourceSignon: {
        icon: '#common-password-key',
        tooltip: 'signon'
      },
      tenant: {
        icon: '#common-multi_tenant',
        tooltip: 'tenant'
      },
      bundleType_renderer: {
        icon: bundleTypeRendererIcon.id || bundleTypeRendererIcon.default.id,
        tooltip: StringResource.get('bundleType_renderer')
      },
      bundleType_schematic: {
        icon: bundleTypeSchematicIcon.id || bundleTypeSchematicIcon.default.id,
        tooltip: StringResource.get('bundleType_schematic')
      }
    },

    /**
     * @param options.$el - JQuery node to append the view onto (either a parent pane or the body)
     * @param options.objectInformation {object} - An object that contains the information for the content
     *
     * @constructor
     */
    init: function init(options) {
      options.objectInformation = options.objectInfo;
      PropertiesPageView.inherited('init', this, arguments);

      _.extend(this, options);

      datasourceApi.glassContext = this.glassContext;

      if (options.propertiesPageViewDefinition) {
        this._oPropertiesPageViewDefintions = options.propertiesPageViewDefinition;
      } else {
        this._oPropertiesPageViewDefintions = JSON.parse(propertiesPageViewDefinitions);
      }

      this.dsController = this._getNewDataSourceListController({
        glassContext: this.glassContext
      });
      this.tenantsController = this._getNewTenantsController({
        glassContext: this.glassContext
      });
      this.apiBase = this._getApiBase({
        glassContext: this.glassContext
      });
    },
    _getApiBase: function _getApiBase(options) {
      return new ApiBase(options);
    },
    _getNewDataSourceListController: function _getNewDataSourceListController(options) {
      return new DataSourceListController(options);
    },
    _getNewTenantsController: function _getNewTenantsController(options) {
      return new TenantsController(options);
    },
    reload: function reload() {
      this.$el.empty();
      this.render();
    },
    _addTabChangeHandler: function _addTabChangeHandler() {
      var tabCon = this._oPropertyUIControl.getProperties()[2];

      tabCon.onTabChange = function () {
        $(this).trigger('tabChanged');
      }.bind(this);
    },
    cannotEditNSObjects: function cannotEditNSObjects(type) {
      var nsObjectTypes = ['namespace', 'namespaceFolder', 'account', 'group', 'role'];
      return nsObjectTypes.indexOf(type) !== -1 && this._isExternalNS();
    },
    _property_name_read_only: function _property_name_read_only() {
      var $editIcon = $(this.$el.find('.banner  .propertyNameEdit'));
      $editIcon.remove();
      var $nameInput = $(this.$el.find('.propertiesBannerLabel.v_defaultName'));
      $nameInput.attr('readonly', 'true');
      $nameInput.css('cursor', 'text');
      var $ic = $(this.$el.find('.propertiesBannerIcon'));
      $ic.css('cursor', 'text');
    },
    render: function render() {
      return PropertiesPageView.inherited('render', this, arguments).then(function () {
        this.$el.addClass('AdminPropPageView');

        this._addTabChangeHandler();

        if (this.type === 'connection') {
          if (this.objectInfo.isNew || this.objectInfo.disabled) {
            this._hideExtraTabs();
          } else {
            this._showExtraTabs();
          }
        } else if (this.type === 'resourceFolder' || this.cannotEditNSObjects(this.type)) {
          this._property_name_read_only();
        } else if (this.type === 'visualization') {
          var bundle = this._objectIcons['bundleType_' + this.objectInfo.bundleType];

          if (bundle) {
            // change icon in title banner
            var $bundleIcon = this.$el.find('.propertyUIControlBanner .propertiesBannerIcon');
            $bundleIcon.attr('title', bundle.tooltip);

            if (this.objectInfo.bundleImage) {
              var classStr = ' class="' + $bundleIcon.find('svg').attr('class') + '" ';
              var srcStr = ' src="' + this.objectInfo.bundleImage + '" ';
              $bundleIcon.find('svg').replaceWith('<img ' + classStr + srcStr + '></img>');
            } else {
              $bundleIcon.find('svg>text').text(bundle.tooltip);
              $bundleIcon.find('svg>use').attr('xlink:href', '#' + bundle.icon);
            } // change type in first row


            var $fileType = this.$el.find('.containerUIControl.propertiesUIControlPageView .propertyRow .propertyDetails .propertyValue.fileType');
            $fileType.text(bundle.tooltip);
          }
        }
      }.bind(this)).catch(function (e) {
        this.logger.debug(e);
      }.bind(this));
    },
    _hideExtraTabs: function _hideExtraTabs() {
      this.slideout.$el.find('.tabNumber2').addClass('disabled').attr('aria-disabled', 'true');
      var $disabledIcon = $('<svg role="presentation" class="svgIcon admin-schema-property-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#common-disabled" x="2" y="0" height="12" width="12" style="stroke: #ff0000;"></use></svg>');
      this.slideout.$el.find('.tabNumber2>a').append($disabledIcon);
    },
    _showExtraTabs: function _showExtraTabs() {
      this.slideout.$el.find('.tabNumber2').removeClass('disabled').removeAttr('aria-disabled');
      this.slideout.$el.find('.tabNumber2>a>svg').remove();
    },
    _getObjectType: function _getObjectType() {
      if (!this.objectInformation.ancestors || this.objectInformation.ancestors.length === 0) {
        return this.objectInformation.type;
      }

      if (this.objectInformation.ancestors[0].type === 'capability') {
        return this.objectInformation.ancestors[0].type;
      }

      return this.objectInformation.type;
    },
    _invalidDataAccount: function _invalidDataAccount(data) {
      var errKey;

      if (this.type === 'account') {
        if (data.password && !/^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/.test(data.password)) {
          errKey = 'passwordInvalidErrorMsg';
        } else if (data.surname !== undefined && $.trim(data.surname) === '') {
          errKey = 'surnameInvalidErrorMsg';
        } else if (data.email && !/^([a-zA-Z0-9]+[_|-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|-|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,3}$/.test(data.email)) {
          errKey = 'emailInvalidErrorMsg';
        }

        if (errKey) {
          this.glassContext.appController.showErrorMessage(StringResource.get(errKey), StringResource.get('error'));
        }
      }

      return errKey !== undefined;
    },
    _invalidData: function _invalidData(data) {
      // Glass always calls hide() on open and close of the slideout. This causes the save request to be done multiple
      // times. To avoid this, the _isSaved flag is used to indicate that save is already done, so not to do another one.
      return this._isSaved || !this.objectInfo.isNew && _.size(data) === 0 || this._invalidDataAccount(data);
    },
    _isBasicType: function _isBasicType() {
      return this.type === 'account' || this.type === 'group' || this.type === 'namespaceFolder' || this.type === 'role';
    },
    _reloadAfterUpdate: function _reloadAfterUpdate() {
      if (this.onUpdate) {
        this.onUpdate();
      }

      if (this.type === 'namespace') {
        _.each(this.parentView.listView.dataAdaptor._accountExplorer._nameSpaces, function (item, index) {
          if (item.id === this.objectInformation.id) {
            this.parentView.listView.dataAdaptor._accountExplorer._nameSpaces[index] = this.objectInformation;
          }
        }.bind(this));
      }

      if (this.parentView.refresh) {
        this.parentView.refresh();
      }
    },
    _isCorDL: function _isCorDL() {
      return this.type === 'contact' || this.type === 'distributionList';
    },
    update: function update() {
      var data;
      var dataDefault = this.objectInformation.defaultName;

      if (this.objectInformation.contactUpdate) {
        data = this.objectInformation.contactUpdate;
        delete this.objectInformation.contactUpdate;
      } else {
        data = this._oPropertyUIControl ? this._oPropertyUIControl.getModifiedProperties() : '';
      }

      if (this._invalidData(data)) {
        return Promise.resolve();
      }

      if (this._isBasicType()) {
        this._convertOptions(data);
      } else if (this.type === 'securedFeature' || this.type === 'securedFunction' || this.type === 'productCapability' || this.type === 'resourceFolder' || this.type === 'cosConnection' || this.type === 'cosLocation') {
        this.objectInformation = _.extend(this.objectInformation, data);
      } else if (this.type !== 'visualization' && this.type !== 'dataSource' && this.type !== 'connection' && this.type !== 'tenant' && !this._isCorDL()) {
        this.parentView.listView.dataAdaptor.sortChanged = true;
        this.objectInformation = _.extend(this.objectInformation, data);
      }

      if (data.defaultName === '') {
        data.defaultName = dataDefault + '_defaultNameWasEmpty';
      }

      return this._save(data).then(this._reloadAfterUpdate.bind(this));
    },
    _getActualValue: function _getActualValue(data, item, val) {
      var temp = _.find(this.objectInformation.options, function (opIt) {
        return opIt.name === item.name;
      });

      var actualValue;

      if (data[val] !== undefined) {
        actualValue = data[val];
      } else if (this.objectInformation.options && temp) {
        actualValue = temp.value;
      } else {
        actualValue = item.value;
      }

      return actualValue;
    },
    _convertOptionsHelper: function _convertOptionsHelper(data, item) {
      var val = item.name;
      var sBidiEnumURL = 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#';

      if (val.indexOf(sBidiEnumURL) === 0) {
        val = val.substring(sBidiEnumURL.length);
      }

      if (this.objectInformation.options) {
        var actualValue = this._getActualValue(data, item, val);

        if (_.isString(actualValue) && actualValue.indexOf(sBidiEnumURL) === 0) {
          this.objectInformation[val] = actualValue.substring(actualValue.lastIndexOf('#') + 1);
        } else {
          this.objectInformation[val] = actualValue;
        }

        item.value = actualValue;
      }
    },
    _convertOptions: function _convertOptions(data) {
      var newOptions = [{
        'name': 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#baseTextDirection',
        'type': 'genericOptionAnyURI',
        'value': 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#biDirectionalFeaturesEnabled#RTL'
      }, {
        'name': 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#biDirectionalFeaturesEnabled',
        'type': 'genericOptionBoolean',
        'value': false
      }, {
        'name': 'showHiddenObjects',
        'type': 'portalOptionBoolean',
        'value': false
      }, {
        'name': 'http:\/\/developer.cognos.com\/ceba\/constants\/systemOptionEnum#accessibilityFeatures',
        'type': 'genericOptionBoolean',
        'value': false
      }, {
        'name': 'showHints',
        'type': 'portalOptionString',
        'value': 'showAll'
      }];

      _.extend(this.objectInformation, data);

      newOptions.forEach(this._convertOptionsHelper.bind(this, data));
      this.objectInformation.options = newOptions;
    },
    onHide: function onHide() {
      if (!this._oPropertyUIControl) {
        return Promise.resolve();
      } else {
        if (this.type === 'connection') {
          //in this case we want to make sure we delete the settings tab
          //as that is taken care of for us
          var tabCon = this._oPropertyUIControl.getProperties()[2];

          if (tabCon && tabCon._tabs) {
            tabCon._tabs.splice(1, 1);
          }
        }

        this.update().then(function () {
          this._oPropertyUIControl.remove();

          if (this.parentView.slideout && this.parentView.slideout.content && this.parentView.slideout.parent.parent && this.parentView.slideout.content.module.indexOf('bi/admin/datasource/slideout') > -1) {
            this.parentView.slideout.remove();
          }
        }.bind(this));
        return Promise.resolve(true);
      }
    },
    _handleError: function _handleError(err) {
      if (AJAXUtils.isNamingConflictErrorMsg(err) || err.status === 409) {
        this.glassContext.appController.showErrorMessage(StringResource.get('nameConflictErrorMsg'), StringResource.get('error'));
      } else {
        this.glassContext.appController.showErrorMessage(err.responseJSON.messages.join('\n'), StringResource.get('error'));
      }
    },
    _updateAccountObject: function _updateAccountObject() {
      var userPrefURL;

      switch (this.type) {
        case 'group':
          userPrefURL = AJAXUtils.getPath('updateGroup', this.objectInformation.id);
          break;

        case 'role':
          userPrefURL = AJAXUtils.getPath('updateRole', this.objectInformation.id);
          break;

        case 'user':
          userPrefURL = AJAXUtils.getPath('updateUser', this.objectInformation.id);
          break;

        case 'namespaceFolder':
          userPrefURL = AJAXUtils.getPath('updateNamespaceFolder', this.objectInformation.id);
          break;

        case 'namespace':
        case 'contact':
        case 'distributionList':
          userPrefURL = AJAXUtils.getPath('updateNamespace', this.objectInformation.id);
          break;

        case 'securedFeature':
        case 'securedFunction':
        case 'productCapability':
          userPrefURL = 'v1/objects/' + this.objectInformation.id;
          break;

        default:
          userPrefURL = '';
          break;
      }

      var options = {
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        type: 'PUT',
        data: JSON.stringify(this.objectInformation.updatedData),
        url: userPrefURL,
        cache: false
      };
      return this.glassContext.services.ajax.ajax(options);
    },
    _updateUserPreferences: function _updateUserPreferences() {
      var userPrefURL = AJAXUtils.getPath('getUserPreference', this.objectInformation.id);
      var options = {
        dataType: 'json',
        type: 'PUT',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(this.objectInformation),
        url: userPrefURL,
        cache: false
      };
      return this.glassContext.services.ajax.ajax(options);
    },
    _save: function _save(data) {
      this._isSaved = true;
      var toastName = data.defaultName ? data.defaultName : this.objectInformation.defaultName;

      if (data.defaultName && data.defaultName.includes('_defaultNameWasEmpty')) {
        this.type = 'error';
      }

      var dfd;

      switch (this.type) {
        case 'account':
          this._setObjectInformationForAccounts(data);

          dfd = this._updateUserPreferences().then(this._showToastHelper.bind(this, toastName));
          break;

        case 'group':
        case 'role':
        case 'namespaceFolder':
          dfd = this._getPropertiesInfo().then(function () {
            this._dataHelper(data);

            return this._updateAccountObject();
          }.bind(this)).then(this._showToastHelper.bind(this, toastName));
          break;

        case 'dataSource':
          dfd = this._saveDataSource(data, toastName);
          break;

        case 'connection':
          dfd = this._saveConnection(data);
          break;

        case 'visualization':
          this._dataHelper(data);

          dfd = this._saveVisualization().then(this._showToastHelper.bind(this, toastName), function (arg, err) {
            this._handleError(err);
          }.bind(this));
          break;

        case 'namespace':
        case 'contact':
        case 'distributionList':
        case 'securedFeature':
        case 'securedFunction':
        case 'productCapability':
          this._dataHelper(data);

          dfd = this._updateAccountObject().then(this._showToastHelper.bind(this, toastName), function (arg, err) {
            this._handleError(err);
          }.bind(this));
          break;

        case 'tenant':
          dfd = this._updateTenant(data);
          break;

        case 'resourceFolder':
          dfd = this.apiBase.updateResourceFolder(this.objectInformation, data);
          break;

        case 'cosConnection':
          dfd = this.apiBase.updateCOSConnection(this.objectInformation, data);
          break;

        case 'cosLocation':
          dfd = this.apiBase.updateCOSLocation(this.objectInformation, data);
          break;

        default:
          this.logger.error('do not know how to handle objects of type ' + this.type);
          dfd = Promise.resolve().then(this._showToastHelper.bind(this, toastName));
      }

      return dfd;
    },
    _setObjectInformationForAccounts: function _setObjectInformationForAccounts(data) {
      if (this.objectInformation.skin) {
        this.objectInformation.skin = this.objectInformation.skin.charAt(0).toUpperCase() + this.objectInformation.skin.slice(1);
      }

      if (this.objectInformation.password) {
        this.objectInformation.password = btoa(this.objectInformation.password);
      }

      if (!this._isAnonymous(this.objectInformation)) {
        this.objectInformation.defaultName = this.objectInformation.givenName + ' ' + this.objectInformation.surname;
      }
    },
    _dataHelper: function _dataHelper(data) {
      this.objectInformation.updatedData = data;
      this.objectInformation.updatedData.type = this.type;

      if (this.type === 'securedFeature' || this.type === 'securedFunction' || this.type === 'productCapability') {
        this.objectInformation.updatedData.type = this.objectInformation.type;
      }
    },
    _saveDataSource: function _saveDataSource(data, toastName) {
      var propertyInfo = {
        'disabled': this.objectInformation.disabled,
        'hidden': this.objectInformation.hidden,
        'hasChildren': this.objectInformation.hasChildren
      };
      $.extend(propertyInfo, data);
      return datasourceApi.dataSources.update(this.objectInformation.id, propertyInfo).then(this._showToastHelper.bind(this, toastName), function (arg, err) {
        this._handleError(err);
      }.bind(this)).then(function () {
        $(this.slideout).trigger('updateObject', this.objectInfo);
      }.bind(this));
    },
    _saveConnection: function _saveConnection(data) {
      $.extend(this.objectInfo, data);

      if (!this.objectInfo.isNew) {
        this._saveExistingConnection();
      }

      return Promise.resolve();
    },
    _saveVisualization: function _saveVisualization() {
      var userPrefURL = AJAXUtils.getPath('updateVisualization', this.objectInformation.id); // visualizations id saved to CM defaultName field.
      // visualizations name saved to CM defaultScreenTip field.

      this.objectInformation.updatedData.defaultScreenTip = this.objectInformation.updatedData.defaultName;
      delete this.objectInformation.updatedData.defaultName;
      var options = {
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        type: 'PUT',
        data: JSON.stringify(this.objectInformation.updatedData),
        url: userPrefURL,
        cache: false
      };
      return this.glassContext.getCoreSvc('.Ajax').ajax(options);
    },
    _showToastHelper: function _showToastHelper(toastName, newData) {
      if (toastName.includes('_defaultNameWasEmpty')) {
        var sText = StringResource.get('toastUpdateFailedMsg', {
          'name': toastName.substring(0, toastName.length - 20)
        });
        this.glassContext.appController.showToast(sText, {
          type: 'info'
        });
      } else {
        var sText = StringResource.get('toastUpdateMsg', {
          'name': toastName
        });
        this.glassContext.appController.showToast(sText, {
          type: 'success'
        });
      }

      return newData;
    },
    setFocus: function setFocus() {
      if (this.objectInfo.isNew) {
        var nameEl = this.$el.find('.v_defaultName');
        $(nameEl).focus();
        $(nameEl).select();
      } else {
        PropertiesPageView.inherited('setFocus', this, arguments);
      }
    },
    _getIdFromLocationHeader: function _getIdFromLocationHeader(response) {
      var location = response.getResponseHeader('location');
      return location.split('/').pop();
    },
    _updateTenant: function _updateTenant(data) {
      var tenantName = data.defaultName !== undefined ? data.defaultName : this.objectInfo.defaultName;
      return this.tenantsController.updateTenant(this.objectInfo.tenantID, data).then(function () {
        this.glassContext.appController.showToast(StringResource.get('multitenancySuccessUpdate', {
          'tenantName': tenantName
        }));
      }.bind(this), function (ajaxOptions, error) {
        this.glassContext.appController.showErrorMessage(StringResource.get('multitenacyFailedUpdate', {
          'tenantName': tenantName
        }) + ', ' + AJAXUtils.buildErrorMessage(error.responseJSON.errors));
      }.bind(this));
    },
    _saveExistingConnection: function _saveExistingConnection() {
      ConnectionUtils.saveConnection(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo, this.connectionSignons, this.removedSignons).then(function () {
        var sText = StringResource.get('datasourceConnectionToastUpdateMsg', {
          'name': this.objectInfo.defaultName
        });
        this.glassContext.appController.showToast(sText, {
          type: 'success'
        });

        if (this.connectionSignons) {
          this.connectionSignons.forEach(function (signon) {
            delete signon.isNew;
          });
        }

        this.removedSignons = [];
        $(this.slideout).trigger('updateObject', this.objectInfo);
      }.bind(this), function () {
        var sText = StringResource.get('datasourceConnectionToastUpdateFailedMsg', {
          'name': this.objectInfo.defaultName
        });
        this.glassContext.appController.showToast(sText, {
          'type': 'error'
        });
      }.bind(this));
    },
    _getPropertiesInfoForAccount: function _getPropertiesInfoForAccount() {
      if (!_.isUndefined(this.accountExplorer)) {
        return new Promise(function (resolve, reject) {
          this.accountExplorer.getAccount(this.objectInformation).then(function (newData) {
            resolve(newData.data[0]);
          }, reject);
        }.bind(this));
      } else {
        return Promise.resolve(this.objectInfo);
      }
    },
    _getPropertiesInfoForConnection: function _getPropertiesInfoForConnection() {
      if (!this.objectInfo.isNew) {
        var conControl = new ConnectionListController({
          glassContext: this.glassContext
        });
        return conControl.getConnection(this.objectInformation.id, this.objectInformation.connId).then(function (newData) {
          newData.dataSourceId = this.objectInfo.dataSourceId;
          return newData;
        }.bind(this));
      } else {
        return Promise.resolve(this.objectInfo);
      }
    },
    _getPropertiesInfoForGroupRoleFolderNS: function _getPropertiesInfoForGroupRoleFolderNS() {
      if (!_.isUndefined(this.accountExplorer)) {
        return new Promise(function (resolve, reject) {
          this.accountExplorer.getItem(this.objectInformation).then(function (newData) {
            resolve(newData.data[0]);
          }, reject);
        }.bind(this));
      } else {
        return Promise.resolve(this.objectInfo);
      }
    },
    _getPropertiesInfoForDataSource: function _getPropertiesInfoForDataSource() {
      return new Promise(function (resolve, reject) {
        this.dsController.getDataSource(this.objectInformation.id).then(function (newData) {
          resolve(newData.data[0]);
        }, reject);
      }.bind(this));
    },
    _getPropertiesInfoForTenant: function _getPropertiesInfoForTenant() {
      return new Promise(function (resolve, reject) {
        this.tenantsController.getTenant(this.objectInformation.tenantID).then(function (tenant) {
          resolve(tenant.data[0]);
        }, reject);
      }.bind(this));
    },
    // visualizations id saved to CM defaultName field.
    // visualizations name saved to CM defaultScreenTip field.
    _getPropertiesInfoForvisualization: function _getPropertiesInfoForvisualization() {
      return this.glassContext.getCoreSvc('.Ajax').ajax({
        dataType: 'json',
        type: 'GET',
        url: 'v1/objects/' + encodeURIComponent(this.objectInformation.id) + '?fields=defaultScreenTip,disabled,hidden,permissions,creationTime,owner.defaultName,hidden,disabled,tenantID,defaultDescription,email,searchPath,ancestors,format,locale,timeZoneID,givenName,surname'
      }).then(function (resp) {
        resp.data.data[0].defaultName = resp.data.data[0].defaultScreenTip;
        return resp.data.data[0];
      }).catch(function (err) {
        this.logger.error(err);
      }.bind(this));
    },
    _getPropertiesInfoCM: function _getPropertiesInfoCM() {
      return this.glassContext.getCoreSvc('.Ajax').ajax({
        dataType: 'json',
        type: 'GET',
        url: 'v1/objects/' + encodeURIComponent(this.objectInformation.id) + '?fields=defaultName,disabled,hidden,permissions,creationTime,owner.defaultName,hidden,disabled,tenantID,defaultDescription,email,searchPath,ancestors,format,locale,timeZoneID,givenName,surname'
      }).then(function (resp) {
        return resp.data.data[0];
      }).catch(function (err) {
        this.logger.error(err);
      }.bind(this));
    },
    _getPropertiesInfoForCapability: function _getPropertiesInfoForCapability() {
      return this.glassContext.getCoreSvc('.Ajax').ajax({
        dataType: 'json',
        type: 'GET',
        url: 'v1/objects/' + encodeURIComponent(this.objectInformation.id) + '?fields=ancestors,disabled,hidden,permissions,creationTime,owner.defaultName,defaultDescription,parent,defaultName,userCapability,policies,hasChildren,searchPath'
      }).then(function (resp) {
        return resp.data.data[0];
      }).catch(function (err) {
        this.logger.error(err);
      }.bind(this));
    },
    _getPropertiesInfoByType: function _getPropertiesInfoByType() {
      var dfd;

      switch (this.type) {
        case 'account':
          dfd = this._getPropertiesInfoForAccount();
          break;

        case 'role':
        case 'group':
        case 'namespace':
        case 'namespaceFolder':
          dfd = this._getPropertiesInfoForGroupRoleFolderNS();
          break;

        case 'dataSource':
          dfd = this._getPropertiesInfoForDataSource();
          break;

        case 'connection':
          dfd = this._getPropertiesInfoForConnection();
          break;

        case 'tenant':
          dfd = this._getPropertiesInfoForTenant();
          break;

        case 'visualization':
          dfd = this._getPropertiesInfoForvisualization();
          break;

        case 'contact':
        case 'distributionList':
          dfd = this._getPropertiesInfoCM();
          break;

        case 'securedFeature':
        case 'securedFunction':
        case 'productCapability':
          dfd = this._getPropertiesInfoForCapability();
          break;

        default:
          dfd = Promise.resolve(this.objectInfo);
      }

      return dfd;
    },
    _getPropertiesInfo: function _getPropertiesInfo() {
      return this._getPropertiesInfoByType().then(function (anObj) {
        this.objectInformation = anObj;
      }.bind(this));
    },
    _isExternalNS: function _isExternalNS() {
      var allowed = ['CAMID(":', 'CAMID("CognosEx:'];

      var isAllowed = _.find(allowed, function (aKey) {
        return this.objectInfo.searchPath.indexOf(aKey) >= 0;
      }.bind(this));

      return this.objectInfo && this.objectInfo.searchPath && !isAllowed;
    },
    _getFileType: function _getFileType() {
      var objectType = this.objectInformation.type;

      if (objectType) {
        return StringResource.get('type_' + objectType.toLowerCase());
      } else {
        return StringResource.get('unknown');
      }
    },
    _isAnonymous: function _isAnonymous(objectInformation) {
      if (objectInformation) {
        return objectInformation.searchPath.indexOf('CAMID("::Anonymous') >= 0;
      } else {
        return false;
      }
    },
    _getSvgIcon: function _getSvgIcon(objInfo) {
      var icon = PropertiesPageView.inherited('_getSvgIcon', this, arguments);

      if (icon === null) {
        if (this._objectIcons[objInfo.type]) {
          icon = this._objectIcons[objInfo.type].icon;
        } else {
          return '#common-question-mark';
        }
      }

      return icon;
    },
    _getSvgTooltip: function _getSvgTooltip(objInfo) {
      var tooltip = PropertiesPageView.inherited('_getSvgTooltip', this, arguments);

      if (_.isUndefined(tooltip)) {
        tooltip = this._objectIcons[objInfo.type].tooltip;
      }

      return tooltip;
    },
    _getTabItems: function _getTabItems() {
      var tabs = this._oPropertiesPageViewDefintions.tabs;
      var currentObjTabs = tabs[this._getObjectType()] || tabs['unknown'] || [];
      return _.map(_.filter(currentObjTabs, this._isTabVisible.bind(this)), this._getTabSpec.bind(this));
    },
    _getTabSpec: function _getTabSpec(tab) {
      return {
        'name': StringResource.get(tab.name),
        'module': tab.module,
        'objectInfo': this.objectInformation,
        'glassContext': this.glassContext,
        'slideout': this.slideout,
        'accountExplorer': this.accountExplorer,
        'selected': this.selectedTabModule === tab.module,
        'connectionResolver': this.connectionResolver
      };
    },
    _isTabVisible: function _isTabVisible(tab) {
      var isVisible = true;

      if (this._isDevOnlyTab(tab) || !this._tabHasCapabilities(tab) || !this._tabHasPermissions(tab) || this._isExternalNameSpaceRole(tab) || this._dataSourceConnShowSchemasCubes(tab) || this._isCQdataServConn(tab) || this._isOIDCNameSpaceGroup(tab)) {
        isVisible = false;
      }

      return isVisible;
    },
    _dataSourceConnShowSchemasCubes: function _dataSourceConnShowSchemasCubes(tab) {
      var hideTab = false;

      if (this._getObjectType() === 'dataSourceConnection' && tab.connectionClass) {
        hideTab = tab.connectionClass !== ConnectionUtils.getConnectionClass(this.objectInformation);
      }

      return hideTab;
    },
    _isCQdataServConn: function _isCQdataServConn(tab) {
      var hideTab = false;

      if (this.objectInformation.isNew) {
        return hideTab;
      }

      if (this._getObjectType() === 'dataSourceConnection' && tab && (tab.name === 'connection_details' || tab.name === 'schemas')) {
        var connectionStringParseResult = ConnectionUtils.parseConnectionString(this.objectInformation);

        if (!connectionStringParseResult.metadata) {
          hideTab = true;
        }
      }

      return hideTab;
    },
    _isOIDCNameSpaceGroup: function _isOIDCNameSpaceGroup(tab) {
      return tab.name === 'members' && this.type === 'group' && this.accountExplorer && this.accountExplorer.isOidcNamespace && this.accountExplorer.isOidcNamespace();
    },
    _isExternalNameSpaceRole: function _isExternalNameSpaceRole(tab) {
      return tab.name === 'customization' && this.type === 'role' && this.accountExplorer && !this.accountExplorer.isBuiltinNamespace();
    },
    _tabHasPermissions: function _tabHasPermissions(tab) {
      return !tab.requiredPermissions || UIHelper.hasPermissions(this.objectInformation.permissions, tab.requiredPermissions);
    },
    _isDevOnlyTab: function _isDevOnlyTab(tab) {
      return !this.glassContext.isDevInstall() && tab.devMode === true;
    },
    _tabHasCapabilities: function _tabHasCapabilities(tab) {
      var hasRequiredCapabilities = true;

      if (tab.requiredCapabilities) {
        hasRequiredCapabilities = _.find(tab.requiredCapabilities, function (capability) {
          return this.glassContext.hasCapability(capability) === false;
        }.bind(this)) === undefined;
      }

      return hasRequiredCapabilities;
    }
  });
  return PropertiesPageView;
});