/*
 * Copyright 2018 JDCLOUD.COM
 *
 * 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.
 *
 * JDCLOUD IAS Services API
 * 京东云联合登陆Api
 *
 * OpenAPI spec version: v1
 * Contact:
 *
 * NOTE: This class is auto generated by the jdcloud code generator program.
 */

require('../../../lib/node_loader')
var JDCloud = require('../../../lib/core')
var Service = JDCloud.Service
var serviceId = 'ias'
Service._services[serviceId] = true

/**
 * ias service.
 * @version 0.2.1
 */

JDCloud.IAS = class IAS extends Service {
  constructor (options = {}) {
    options._defaultEndpoint = {}
    options._defaultEndpoint.protocol =
      options._defaultEndpoint.protocol || 'https'
    options._defaultEndpoint.host =
      options._defaultEndpoint.host || 'ias.jdcloud-api.com'
    options.basePath = '/v1' // 默认要设为空""
    super(serviceId, options)
  }

  /**
      *  运营后台查询app
      * @param {Object} opts - parameters
      * @param {string} opts.pin - pin
      * @param {string} opts.appName - appName
      * @param {string} opts.clientId - clientId
      * @param {boolean} opts.multiTenant - multiTenant
      * @param {string} opts.state - state
      * @param {string} opts.scope - scope
      * @param {integer} opts.startTime - startTime
      * @param {integer} opts.endTime - endTime
      * @param {string} opts.accountType - accountType
      * @param {integer} opts.pageIndex - pageIndex
      * @param {integer} opts.pageSize - pageSize
      * @param {integer} opts.offset - offset
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param pagination pagination
      * @param appQueryResultItem result
      */

  apps (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  apps"
      )
    }

    opts = opts || {}

    if (opts.pin === undefined || opts.pin === null) {
      throw new Error(
        "Missing the required parameter 'opts.pin' when calling apps"
      )
    }
    if (opts.appName === undefined || opts.appName === null) {
      throw new Error(
        "Missing the required parameter 'opts.appName' when calling apps"
      )
    }
    if (opts.clientId === undefined || opts.clientId === null) {
      throw new Error(
        "Missing the required parameter 'opts.clientId' when calling apps"
      )
    }
    if (opts.multiTenant === undefined || opts.multiTenant === null) {
      throw new Error(
        "Missing the required parameter 'opts.multiTenant' when calling apps"
      )
    }
    if (opts.state === undefined || opts.state === null) {
      throw new Error(
        "Missing the required parameter 'opts.state' when calling apps"
      )
    }
    if (opts.scope === undefined || opts.scope === null) {
      throw new Error(
        "Missing the required parameter 'opts.scope' when calling apps"
      )
    }
    if (opts.startTime === undefined || opts.startTime === null) {
      throw new Error(
        "Missing the required parameter 'opts.startTime' when calling apps"
      )
    }
    if (opts.endTime === undefined || opts.endTime === null) {
      throw new Error(
        "Missing the required parameter 'opts.endTime' when calling apps"
      )
    }
    if (opts.accountType === undefined || opts.accountType === null) {
      throw new Error(
        "Missing the required parameter 'opts.accountType' when calling apps"
      )
    }
    if (opts.pageIndex === undefined || opts.pageIndex === null) {
      throw new Error(
        "Missing the required parameter 'opts.pageIndex' when calling apps"
      )
    }
    if (opts.pageSize === undefined || opts.pageSize === null) {
      throw new Error(
        "Missing the required parameter 'opts.pageSize' when calling apps"
      )
    }
    if (opts.offset === undefined || opts.offset === null) {
      throw new Error(
        "Missing the required parameter 'opts.offset' when calling apps"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.pin !== undefined && opts.pin !== null) {
      queryParams['pin'] = opts.pin
    }
    if (opts.appName !== undefined && opts.appName !== null) {
      queryParams['appName'] = opts.appName
    }
    if (opts.clientId !== undefined && opts.clientId !== null) {
      queryParams['clientId'] = opts.clientId
    }
    if (opts.multiTenant !== undefined && opts.multiTenant !== null) {
      queryParams['multiTenant'] = opts.multiTenant
    }
    if (opts.state !== undefined && opts.state !== null) {
      queryParams['state'] = opts.state
    }
    if (opts.scope !== undefined && opts.scope !== null) {
      queryParams['scope'] = opts.scope
    }
    if (opts.startTime !== undefined && opts.startTime !== null) {
      queryParams['startTime'] = opts.startTime
    }
    if (opts.endTime !== undefined && opts.endTime !== null) {
      queryParams['endTime'] = opts.endTime
    }
    if (opts.accountType !== undefined && opts.accountType !== null) {
      queryParams['accountType'] = opts.accountType
    }
    if (opts.pageIndex !== undefined && opts.pageIndex !== null) {
      queryParams['pageIndex'] = opts.pageIndex
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    if (opts.offset !== undefined && opts.offset !== null) {
      queryParams['offset'] = opts.offset
    }

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call apps with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/operate_backend/apps',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  运营后台获取应用详情
      * @param {Object} opts - parameters
      * @param {string} opts.clientId
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string clientId  应用
      * @param string clientName  应用名
      * @param string tokenEndpointAuthMethod  tokenEndpointAuthMethod
      * @param string grantTypes  grantTypes
      * @param string responseTypes  responseTypes
      * @param string redirectUris  redirectUris
      * @param string clientUri  clientUri
      * @param string logoUri  logoUri
      * @param string tosUri  tosUri
      * @param string policyUri  policyUri
      * @param string scope  scope
      * @param string jwksUri  jwksUri
      * @param string jwks  jwks
      * @param string contacts  contacts
      * @param string extension  extension
      * @param integer accessTokenValiditySeconds  accessTokenValiditySeconds
      * @param integer refreshTokenValiditySeconds  refreshTokenValiditySeconds
      * @param boolean multiTenant  multiTenant
      * @param integer secretUpdateTime  secretUpdateTime
      * @param integer updateTime  updateTime
      * @param integer createTime  createTime
      * @param string account  account
      * @param string userType  userType
      * @param string state  state
      */

  appDetail (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  appDetail"
      )
    }

    opts = opts || {}

    if (opts.clientId === undefined || opts.clientId === null) {
      throw new Error(
        "Missing the required parameter 'opts.clientId' when calling appDetail"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      clientId: opts.clientId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call appDetail with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/operate_backend/app/{clientId}',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  运营后台获取应用状态
      * @param {Object} opts - parameters
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param state states
      */

  state (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  state"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call state with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/operate_backend/state',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  创建应用
      * @param {Object} opts - parameters
      * @param {string} [opts.clientName] - 应用名  optional
      * @param {string} [opts.tokenEndpointAuthMethod] - 客户端认证方式&lt;br&gt; - none：不设置客户端密码（不推荐）&lt;br&gt; - client_secret_post：客户端必须设置密码，且该密码需要在OAuth2 Token Endpoint提供于请求的body&lt;br&gt; - client_secret_basic：客户端必须设置密码，且该密码需要在OAuth2 Token Endpoint提供于请求的header&lt;br&gt; 支持以下值：&lt;br&gt; （1）none&lt;br&gt; （2）client_secret_post&lt;br&gt; （3）client_secret_basic  optional
      * @param {string} [opts.grantTypes] - 支持的OAuth类型：&lt;br&gt; - authorization_code：OAuth2授权码模式&lt;br&gt; - implicit：OAuth2隐式授权模式&lt;br&gt; - refresh_token：启用刷新令牌 支持以下值：&lt;br&gt; （1）authorization_code&lt;br&gt; （2）authorization_code,refresh_token&lt;br&gt; （3）authorization_code,implicit&lt;br&gt; （4）authorization_code,implicit,refresh_token&lt;br&gt; （5）implicit&lt;br&gt; 注：如果grantTypes指定了refresh_token，应用将可以使用刷新令牌；如果在创建应用时未指定，则应用不能使用刷新令牌；任何时候应用都可以调用“更新应用”接口更改grantTypes设置  optional
      * @param {string} [opts.redirectUris] - 回调地址，最多4个，多个url之间用逗号,分隔，每个url长度不超过1000，url不支持#符号  optional
      * @param {string} [opts.clientUri] - 应用介绍地址，url不支持#符号  optional
      * @param {string} [opts.logoUri] - 应用logo地址，url不支持#符号  optional
      * @param {string} [opts.tosUri] - 应用服务协议地址，url不支持#符号  optional
      * @param {string} [opts.policyUri] - 应用隐私政策地址，url不支持#符号  optional
      * @param {string} [opts.scope] - OAuth scope范围，支持的值为：&lt;br/&gt; （1）openid：用OpenID Connect协议进行身份认证&lt;br/&gt; 指定scope为openid，并在Authorization Endpoint请求该scope，京东云将返回用户的OpenID令牌；如果在创建应用时未指明该值，则应用不能请求OpenID令牌；任何时候应用都可以调用“更新应用”更改该设置  optional
      * @param {string} [opts.jwksUri] - JWKS地址，url不支持#符号&lt;br/&gt;jwksUri和jwks传一个即可  optional
      * @param {string} [opts.jwks] - JWKS  optional
      * @param {string} [opts.contacts] - 应用联系信息  optional
      * @param {string} [opts.extension] - 应用扩展信息  optional
      * @param {integer} [opts.accessTokenValiditySeconds] - 访问令牌有效期，值的范围为 600 秒到 6x3600&#x3D;21,600 秒，即10分钟-6小时  optional
      * @param {integer} [opts.refreshTokenValiditySeconds] - 刷新令牌有效期，值的范围为 30x24x3600&#x3D;2,592,000 秒到 365x24x3600&#x3D;31,536,000 秒，即30天-365天&lt;br/&gt;&lt;br/&gt; 注：当 GrantTypes 包含 refresh_token 时，refreshTokenValiditySeconds 为必传参数  optional
      * @param {boolean} [opts.multiTenant] - 是否为多租户应用&lt;br/&gt; &quot;false&quot;：该应用仅支持当前创建应用的租户访问，其他京东云租户无法访问&lt;br/&gt;        &quot;true&quot;：该应用支持其他京东云租户访问，但当前创建应用的租户不能访问  optional
      * @param {string} [opts.secret] - 应用的密码，支持8-255位长度的ASCII可打印字符，建议使用足够复杂的密码策略&lt;br/&gt;&lt;br/&gt;        注：当TokenEndpointAuthMethod不等于none时，secret为必传参数；反之，当指定了secret时，TokenEndpointAuthMethod不能等于none&lt;br/&gt;京东云将不可逆加密secret，因此您无法再次从京东云查看该密码，但您可以随时通过更新应用重新设置secret  optional
      * @param {string} [opts.userType] - 能访问应用的账号类型，支持以下值：&lt;br/&gt; （1）root：支持主账号访问，子用户无法访问&lt;br/&gt; （2）sub：子用户账号，使用主账号不能访问&lt;br/&gt;&lt;br/&gt; 注：multiTenant和userType的组合指定了应用的用户人群，典型的应用场景如：&lt;br/&gt; （1）应用向当前租户下的子用户开放（2）应用向京东云其他租户主账号开放  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string clientId  应用ID，由京东云分配的16位数字ID
      * @param string clientName  clientName参数值
      * @param string tokenEndpointAuthMethod  tokenEndpointAuthMethod参数值
      * @param string grantTypes  grantTypes参数值
      * @param string responseTypes  当grantTypes为authorization_code时，responseTypes为code；当grantTypes为implicit时，responseTypes为token
      * @param string redirectUris  redirectUris参数值
      * @param string clientUri  clientUri参数值
      * @param string logoUri  logoUri参数值
      * @param string tosUri  tosUri参数值
      * @param string policyUri  policyUri参数值
      * @param string scope  scope参数值
      * @param string jwksUri  jwksUri参数值
      * @param string jwks  jwks参数值
      * @param string contacts  contacts参数值
      * @param string extension  extension参数值
      * @param integer accessTokenValiditySeconds  accessTokenValiditySeconds参数值
      * @param integer refreshTokenValiditySeconds  refreshTokenValiditySeconds参数值
      * @param boolean multiTenant  multiTenant参数值
      * @param integer secretUpdateTime  secretUpdateTime参数值
      * @param integer updateTime  updateTime参数值
      * @param integer createTime  createTime参数值
      * @param string account  创建应用的账户用户名
      * @param string userType  userType参数值
      */

  createApp (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  createApp"
      )
    }

    opts = opts || {}

    let postBody = {}
    if (opts.clientName !== undefined && opts.clientName !== null) {
      postBody['clientName'] = opts.clientName
    }
    if (
      opts.tokenEndpointAuthMethod !== undefined &&
      opts.tokenEndpointAuthMethod !== null
    ) {
      postBody['tokenEndpointAuthMethod'] = opts.tokenEndpointAuthMethod
    }
    if (opts.grantTypes !== undefined && opts.grantTypes !== null) {
      postBody['grantTypes'] = opts.grantTypes
    }
    if (opts.redirectUris !== undefined && opts.redirectUris !== null) {
      postBody['redirectUris'] = opts.redirectUris
    }
    if (opts.clientUri !== undefined && opts.clientUri !== null) {
      postBody['clientUri'] = opts.clientUri
    }
    if (opts.logoUri !== undefined && opts.logoUri !== null) {
      postBody['logoUri'] = opts.logoUri
    }
    if (opts.tosUri !== undefined && opts.tosUri !== null) {
      postBody['tosUri'] = opts.tosUri
    }
    if (opts.policyUri !== undefined && opts.policyUri !== null) {
      postBody['policyUri'] = opts.policyUri
    }
    if (opts.scope !== undefined && opts.scope !== null) {
      postBody['scope'] = opts.scope
    }
    if (opts.jwksUri !== undefined && opts.jwksUri !== null) {
      postBody['jwksUri'] = opts.jwksUri
    }
    if (opts.jwks !== undefined && opts.jwks !== null) {
      postBody['jwks'] = opts.jwks
    }
    if (opts.contacts !== undefined && opts.contacts !== null) {
      postBody['contacts'] = opts.contacts
    }
    if (opts.extension !== undefined && opts.extension !== null) {
      postBody['extension'] = opts.extension
    }
    if (
      opts.accessTokenValiditySeconds !== undefined &&
      opts.accessTokenValiditySeconds !== null
    ) {
      postBody['accessTokenValiditySeconds'] = opts.accessTokenValiditySeconds
    }
    if (
      opts.refreshTokenValiditySeconds !== undefined &&
      opts.refreshTokenValiditySeconds !== null
    ) {
      postBody['refreshTokenValiditySeconds'] = opts.refreshTokenValiditySeconds
    }
    if (opts.multiTenant !== undefined && opts.multiTenant !== null) {
      postBody['multiTenant'] = opts.multiTenant
    }
    if (opts.secret !== undefined && opts.secret !== null) {
      postBody['secret'] = opts.secret
    }
    if (opts.userType !== undefined && opts.userType !== null) {
      postBody['userType'] = opts.userType
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call createApp with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/app',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  获取应用
      * @param {Object} opts - parameters
      * @param {string} opts.clientId - 应用ID，应用创建时由京东云分配的16位数字ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string clientId  应用ID，由京东云分配的16位数字ID
      * @param string clientName  应用名
      * @param string tokenEndpointAuthMethod  客户端认证方式
      * @param string grantTypes  支持的OAuth类型
      * @param string responseTypes  当grantTypes为authorization_code时，responseTypes为code；当grantTypes为implicit时，responseTypes为token
      * @param string redirectUris  回调地址
      * @param string clientUri  应用介绍地址
      * @param string logoUri  应用logo地址
      * @param string tosUri  应用服务协议地址
      * @param string policyUri  应用隐私条款地址
      * @param string scope  OAuth scope授权范围
      * @param string jwksUri  JWKS地址
      * @param string jwks  JWKS
      * @param string contacts  应用联系信息
      * @param string extension  应用扩展信息
      * @param integer accessTokenValiditySeconds  访问令牌有效期
      * @param integer refreshTokenValiditySeconds  刷新令牌有效期
      * @param boolean multiTenant  是否为多租户应用
      * @param integer secretUpdateTime  应用密码更新时间
      * @param integer updateTime  应用更新时间
      * @param integer createTime  应用创建时间
      * @param string account  创建应用的账户用户名
      * @param string userType  允许登录应用的账号类型
      */

  getApp (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  getApp"
      )
    }

    opts = opts || {}

    if (opts.clientId === undefined || opts.clientId === null) {
      throw new Error(
        "Missing the required parameter 'opts.clientId' when calling getApp"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      clientId: opts.clientId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call getApp with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/app/{clientId}',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  更新应用（只传需要变更的参数，不传的参数不会更新）
      * @param {Object} opts - parameters
      * @param {string} opts.clientId - 应用ID，应用创建时由京东云分配的16位数字ID
      * @param {string} [opts.clientName] - 应用名  optional
      * @param {string} [opts.tokenEndpointAuthMethod] - 客户端认证方式：&lt;br/&gt; none：不设置客户端密码（不推荐）&lt;br/&gt; client_secret_post：客户端必须设置密码，且该密码需要在OAuth2 Token Endpoint提供于请求的body&lt;br/&gt; client_secret_basic：客户端必须设置密码，且该密码需要在OAuth2 Token Endpoint提供于请求的header&lt;br/&gt;&lt;br/&gt; 支持以下值：&lt;br/&gt; （1）none&lt;br/&gt; （2）client_secret_post&lt;br/&gt; （3）client_secret_basic  optional
      * @param {string} [opts.grantTypes] - 支持的OAuth类型：&lt;br/&gt; authorization_code：OAuth2授权码模式&lt;br/&gt; implicit：OAuth2隐式授权模式&lt;br/&gt; refresh_token：启用刷新令牌&lt;br/&gt;&lt;br/&gt; 支持以下值：&lt;br/&gt; （1）authorization_code&lt;br/&gt; （2）authorization_code,refresh_token&lt;br/&gt; （3）authorization_code,implicit&lt;br/&gt; （4）authorization_code,implicit,refresh_token&lt;br/&gt; （5）implicit&lt;br/&gt;&lt;br/&gt;        注：如果grantTypes指定了refresh_token，应用将可以使用刷新令牌；如果在创建应用时未指定，则应用不能使用刷新令牌；任何时候应用都可以调用“更新应用”接口更改grantTypes设置  optional
      * @param {string} [opts.redirectUris] - 回调地址，最多4个，多个url之间用逗号,分隔，每个url长度不超过1000，url不支持#符号  optional
      * @param {string} [opts.clientUri] - 应用介绍地址，url不支持#符号  optional
      * @param {string} [opts.logoUri] - 应用logo地址，url不支持#符号  optional
      * @param {string} [opts.tosUri] - 应用服务协议地址，url不支持#符号  optional
      * @param {string} [opts.policyUri] - 应用隐私政策地址，url不支持#符号  optional
      * @param {string} [opts.scope] - OAuth scope范围，支持的值为：&lt;br/&gt; （1）openid：用OpenID Connect协议进行身份认证&lt;br/&gt; 指定scope为openid，并在Authorization Endpoint请求该scope，京东云将返回用户的OpenID令牌；如果在创建应用时未指明该值，则应用不能请求OpenID令牌；任何时候应用都可以调用“更新应用”更改该设置  optional
      * @param {string} [opts.jwksUri] - JWKS地址，url不支持#符号&lt;br/&gt; jwksUri和jwks传一个即可  optional
      * @param {string} [opts.jwks] - JWKS  optional
      * @param {string} [opts.contacts] - 应用联系信息  optional
      * @param {string} [opts.extension] - 应用扩展信息  optional
      * @param {integer} [opts.accessTokenValiditySeconds] - 访问令牌有效期，值的范围为 600 秒到 6x3600&#x3D;21,600 秒，即10分钟-6小时  optional
      * @param {integer} [opts.refreshTokenValiditySeconds] - 刷新令牌有效期，值的范围为 30x24x3600&#x3D;2,592,000 秒到 365x24x3600&#x3D;31,536,000 秒，即30天-365天&lt;br/&gt;&lt;br/&gt; 注：当 GrantTypes 包含 refresh_token 时，refreshTokenValiditySeconds 为必传参数  optional
      * @param {boolean} [opts.multiTenant] - 是否为多租户应用&lt;br/&gt; &quot;false&quot;：该应用仅支持当前创建应用的租户访问，其他京东云租户无法访问&lt;br/&gt;        &quot;true&quot;：该应用支持其他京东云租户访问，但当前创建应用的租户不能访问  optional
      * @param {string} [opts.secret] - 应用的密码，支持8-255位长度的ASCII可打印字符，建议使用足够复杂的密码策略&lt;br/&gt;&lt;br/&gt; 注：当TokenEndpointAuthMethod不等于none时，secret为必传参数；反之，当指定了secret时，TokenEndpointAuthMethod不能等于none&lt;br/&gt; 京东云将不可逆加密secret，因此您无法再次从京东云查看该密码，但您可以随时通过更新应用重新设置secret  optional
      * @param {string} [opts.userType] - 能访问应用的账号类型，支持以下值：&lt;br/&gt; （1）root：支持主账号访问，子用户无法访问&lt;br/&gt; （2）sub：子用户账号，使用主账号不能访问&lt;br/&gt;&lt;br/&gt; 注：multiTenant和userType的组合指定了应用的用户人群，典型的应用场景如：&lt;br/&gt; （1）应用向当前租户下的子用户开放（2）应用向京东云其他租户主账号开放  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string clientId  应用ID，由京东云分配的16位数字ID
      * @param string clientName  clientName参数值
      * @param string tokenEndpointAuthMethod  tokenEndpointAuthMethod参数值
      * @param string grantTypes  grantTypes参数值
      * @param string responseTypes  当grantTypes为authorization_code时，responseTypes为code；当grantTypes为implicit时，responseTypes为token
      * @param string redirectUris  redirectUris参数值
      * @param string clientUri  clientUri参数值
      * @param string logoUri  logoUri参数值
      * @param string tosUri  tosUri参数值
      * @param string policyUri  policyUri参数值
      * @param string scope  scope参数值
      * @param string jwksUri  jwksUri参数值
      * @param string jwks  jwks参数值
      * @param string contacts  contacts参数值
      * @param string extension  extension参数值
      * @param integer accessTokenValiditySeconds  accessTokenValiditySeconds参数值
      * @param integer refreshTokenValiditySeconds  refreshTokenValiditySeconds参数值
      * @param boolean multiTenant  multiTenant参数值
      * @param integer secretUpdateTime  secretUpdateTime参数值
      * @param integer updateTime  updateTime参数值
      * @param integer createTime  createTime参数值
      * @param string account  创建应用的账户用户名
      * @param string userType  userType参数值
      */

  updateApp (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  updateApp"
      )
    }

    opts = opts || {}

    if (opts.clientId === undefined || opts.clientId === null) {
      throw new Error(
        "Missing the required parameter 'opts.clientId' when calling updateApp"
      )
    }

    let postBody = {}
    if (opts.clientName !== undefined && opts.clientName !== null) {
      postBody['clientName'] = opts.clientName
    }
    if (
      opts.tokenEndpointAuthMethod !== undefined &&
      opts.tokenEndpointAuthMethod !== null
    ) {
      postBody['tokenEndpointAuthMethod'] = opts.tokenEndpointAuthMethod
    }
    if (opts.grantTypes !== undefined && opts.grantTypes !== null) {
      postBody['grantTypes'] = opts.grantTypes
    }
    if (opts.redirectUris !== undefined && opts.redirectUris !== null) {
      postBody['redirectUris'] = opts.redirectUris
    }
    if (opts.clientUri !== undefined && opts.clientUri !== null) {
      postBody['clientUri'] = opts.clientUri
    }
    if (opts.logoUri !== undefined && opts.logoUri !== null) {
      postBody['logoUri'] = opts.logoUri
    }
    if (opts.tosUri !== undefined && opts.tosUri !== null) {
      postBody['tosUri'] = opts.tosUri
    }
    if (opts.policyUri !== undefined && opts.policyUri !== null) {
      postBody['policyUri'] = opts.policyUri
    }
    if (opts.scope !== undefined && opts.scope !== null) {
      postBody['scope'] = opts.scope
    }
    if (opts.jwksUri !== undefined && opts.jwksUri !== null) {
      postBody['jwksUri'] = opts.jwksUri
    }
    if (opts.jwks !== undefined && opts.jwks !== null) {
      postBody['jwks'] = opts.jwks
    }
    if (opts.contacts !== undefined && opts.contacts !== null) {
      postBody['contacts'] = opts.contacts
    }
    if (opts.extension !== undefined && opts.extension !== null) {
      postBody['extension'] = opts.extension
    }
    if (
      opts.accessTokenValiditySeconds !== undefined &&
      opts.accessTokenValiditySeconds !== null
    ) {
      postBody['accessTokenValiditySeconds'] = opts.accessTokenValiditySeconds
    }
    if (
      opts.refreshTokenValiditySeconds !== undefined &&
      opts.refreshTokenValiditySeconds !== null
    ) {
      postBody['refreshTokenValiditySeconds'] = opts.refreshTokenValiditySeconds
    }
    if (opts.multiTenant !== undefined && opts.multiTenant !== null) {
      postBody['multiTenant'] = opts.multiTenant
    }
    if (opts.secret !== undefined && opts.secret !== null) {
      postBody['secret'] = opts.secret
    }
    if (opts.userType !== undefined && opts.userType !== null) {
      postBody['userType'] = opts.userType
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      clientId: opts.clientId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call updateApp with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/app/{clientId}',
      'PUT',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  删除应用
      * @param {Object} opts - parameters
      * @param {string} opts.clientId - 应用ID，应用创建时由京东云分配的16位数字ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param integer count  删除结果[1:删除成功,0:删除失败]
      */

  deleteApp (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  deleteApp"
      )
    }

    opts = opts || {}

    if (opts.clientId === undefined || opts.clientId === null) {
      throw new Error(
        "Missing the required parameter 'opts.clientId' when calling deleteApp"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      clientId: opts.clientId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call deleteApp with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/app/{clientId}',
      'DELETE',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  获取账户下所有应用
      * @param {Object} opts - parameters
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param applicationRes apps
      */

  getApps (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  getApps"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  ias/0.2.1'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call getApps with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/apps',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }
}
module.exports = JDCloud.IAS
