"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Params = exports.OpenApiRequest = exports.Config = exports.GlobalParameters = void 0;
// This file is auto-generated, don't edit it
/**
 * @remarks
 * This is for OpenApi SDK
 */
const tea_util_1 = __importDefault(require("@alicloud/tea-util"));
const credentials_1 = __importStar(require("@alicloud/credentials")), $Credential = credentials_1;
const openapi_util_1 = __importDefault(require("@alicloud/openapi-util"));
const $SPI = __importStar(require("@alicloud/gateway-spi"));
const tea_xml_1 = __importDefault(require("@alicloud/tea-xml"));
const $tea = __importStar(require("@alicloud/tea-typescript"));
class GlobalParameters extends $tea.Model {
    static names() {
        return {
            headers: 'headers',
            queries: 'queries',
        };
    }
    static types() {
        return {
            headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },
            queries: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },
        };
    }
    constructor(map) {
        super(map);
    }
}
exports.GlobalParameters = GlobalParameters;
/**
 * @remarks
 * Model for initing client
 */
class Config extends $tea.Model {
    static names() {
        return {
            accessKeyId: 'accessKeyId',
            accessKeySecret: 'accessKeySecret',
            securityToken: 'securityToken',
            bearerToken: 'bearerToken',
            protocol: 'protocol',
            method: 'method',
            regionId: 'regionId',
            readTimeout: 'readTimeout',
            connectTimeout: 'connectTimeout',
            httpProxy: 'httpProxy',
            httpsProxy: 'httpsProxy',
            credential: 'credential',
            endpoint: 'endpoint',
            noProxy: 'noProxy',
            maxIdleConns: 'maxIdleConns',
            network: 'network',
            userAgent: 'userAgent',
            suffix: 'suffix',
            socks5Proxy: 'socks5Proxy',
            socks5NetWork: 'socks5NetWork',
            endpointType: 'endpointType',
            openPlatformEndpoint: 'openPlatformEndpoint',
            type: 'type',
            signatureVersion: 'signatureVersion',
            signatureAlgorithm: 'signatureAlgorithm',
            globalParameters: 'globalParameters',
            key: 'key',
            cert: 'cert',
            ca: 'ca',
            disableHttp2: 'disableHttp2',
            tlsMinVersion: 'tlsMinVersion',
        };
    }
    static types() {
        return {
            accessKeyId: 'string',
            accessKeySecret: 'string',
            securityToken: 'string',
            bearerToken: 'string',
            protocol: 'string',
            method: 'string',
            regionId: 'string',
            readTimeout: 'number',
            connectTimeout: 'number',
            httpProxy: 'string',
            httpsProxy: 'string',
            credential: credentials_1.default,
            endpoint: 'string',
            noProxy: 'string',
            maxIdleConns: 'number',
            network: 'string',
            userAgent: 'string',
            suffix: 'string',
            socks5Proxy: 'string',
            socks5NetWork: 'string',
            endpointType: 'string',
            openPlatformEndpoint: 'string',
            type: 'string',
            signatureVersion: 'string',
            signatureAlgorithm: 'string',
            globalParameters: GlobalParameters,
            key: 'string',
            cert: 'string',
            ca: 'string',
            disableHttp2: 'boolean',
            tlsMinVersion: 'string',
        };
    }
    constructor(map) {
        super(map);
    }
}
exports.Config = Config;
class OpenApiRequest extends $tea.Model {
    static names() {
        return {
            headers: 'headers',
            query: 'query',
            body: 'body',
            stream: 'stream',
            hostMap: 'hostMap',
            endpointOverride: 'endpointOverride',
        };
    }
    static types() {
        return {
            headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },
            query: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },
            body: 'any',
            stream: 'Readable',
            hostMap: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },
            endpointOverride: 'string',
        };
    }
    constructor(map) {
        super(map);
    }
}
exports.OpenApiRequest = OpenApiRequest;
class Params extends $tea.Model {
    static names() {
        return {
            action: 'action',
            version: 'version',
            protocol: 'protocol',
            pathname: 'pathname',
            method: 'method',
            authType: 'authType',
            bodyType: 'bodyType',
            reqBodyType: 'reqBodyType',
            style: 'style',
        };
    }
    static types() {
        return {
            action: 'string',
            version: 'string',
            protocol: 'string',
            pathname: 'string',
            method: 'string',
            authType: 'string',
            bodyType: 'string',
            reqBodyType: 'string',
            style: 'string',
        };
    }
    constructor(map) {
        super(map);
    }
}
exports.Params = Params;
class Client {
    /**
     * @remarks
     * Init client with Config
     *
     * @param config - config contains the necessary information to create a client
     */
    constructor(config) {
        if (tea_util_1.default.isUnset(config)) {
            throw $tea.newError({
                code: "ParameterMissing",
                message: "'config' can not be unset",
            });
        }
        if (!tea_util_1.default.empty(config.accessKeyId) && !tea_util_1.default.empty(config.accessKeySecret)) {
            if (!tea_util_1.default.empty(config.securityToken)) {
                config.type = "sts";
            }
            else {
                config.type = "access_key";
            }
            let credentialConfig = new $Credential.Config({
                accessKeyId: config.accessKeyId,
                type: config.type,
                accessKeySecret: config.accessKeySecret,
            });
            credentialConfig.securityToken = config.securityToken;
            this._credential = new credentials_1.default(credentialConfig);
        }
        else if (!tea_util_1.default.empty(config.bearerToken)) {
            let cc = new $Credential.Config({
                type: "bearer",
                bearerToken: config.bearerToken,
            });
            this._credential = new credentials_1.default(cc);
        }
        else if (!tea_util_1.default.isUnset(config.credential)) {
            this._credential = config.credential;
        }
        this._endpoint = config.endpoint;
        this._endpointType = config.endpointType;
        this._network = config.network;
        this._suffix = config.suffix;
        this._protocol = config.protocol;
        this._method = config.method;
        this._regionId = config.regionId;
        this._userAgent = config.userAgent;
        this._readTimeout = config.readTimeout;
        this._connectTimeout = config.connectTimeout;
        this._httpProxy = config.httpProxy;
        this._httpsProxy = config.httpsProxy;
        this._noProxy = config.noProxy;
        this._socks5Proxy = config.socks5Proxy;
        this._socks5NetWork = config.socks5NetWork;
        this._maxIdleConns = config.maxIdleConns;
        this._signatureVersion = config.signatureVersion;
        this._signatureAlgorithm = config.signatureAlgorithm;
        this._globalParameters = config.globalParameters;
        this._key = config.key;
        this._cert = config.cert;
        this._ca = config.ca;
        this._disableHttp2 = config.disableHttp2;
        this._tlsMinVersion = config.tlsMinVersion;
    }
    /**
     * @remarks
     * Encapsulate the request and invoke the network
     *
     * @param action - api name
     * @param version - product version
     * @param protocol - http or https
     * @param method - e.g. GET
     * @param authType - authorization type e.g. AK
     * @param bodyType - response body type e.g. String
     * @param request - object of OpenApiRequest
     * @param runtime - which controls some details of call api, such as retry times
     * @returns the response
     */
    async doRPCRequest(action, version, protocol, method, authType, bodyType, request, runtime) {
        let _runtime = {
            timeouted: "retry",
            key: tea_util_1.default.defaultString(runtime.key, this._key),
            cert: tea_util_1.default.defaultString(runtime.cert, this._cert),
            ca: tea_util_1.default.defaultString(runtime.ca, this._ca),
            readTimeout: tea_util_1.default.defaultNumber(runtime.readTimeout, this._readTimeout),
            connectTimeout: tea_util_1.default.defaultNumber(runtime.connectTimeout, this._connectTimeout),
            httpProxy: tea_util_1.default.defaultString(runtime.httpProxy, this._httpProxy),
            httpsProxy: tea_util_1.default.defaultString(runtime.httpsProxy, this._httpsProxy),
            noProxy: tea_util_1.default.defaultString(runtime.noProxy, this._noProxy),
            socks5Proxy: tea_util_1.default.defaultString(runtime.socks5Proxy, this._socks5Proxy),
            socks5NetWork: tea_util_1.default.defaultString(runtime.socks5NetWork, this._socks5NetWork),
            maxIdleConns: tea_util_1.default.defaultNumber(runtime.maxIdleConns, this._maxIdleConns),
            retry: {
                retryable: runtime.autoretry,
                maxAttempts: tea_util_1.default.defaultNumber(runtime.maxAttempts, 3),
            },
            backoff: {
                policy: tea_util_1.default.defaultString(runtime.backoffPolicy, "no"),
                period: tea_util_1.default.defaultNumber(runtime.backoffPeriod, 1),
            },
            ignoreSSL: runtime.ignoreSSL,
            tlsMinVersion: this._tlsMinVersion,
        };
        let _lastRequest = null;
        let _now = Date.now();
        let _retryTimes = 0;
        while ($tea.allowRetry(_runtime['retry'], _retryTimes, _now)) {
            if (_retryTimes > 0) {
                let _backoffTime = $tea.getBackoffTime(_runtime['backoff'], _retryTimes);
                if (_backoffTime > 0) {
                    await $tea.sleep(_backoffTime);
                }
            }
            _retryTimes = _retryTimes + 1;
            try {
                let request_ = new $tea.Request();
                request_.protocol = tea_util_1.default.defaultString(this._protocol, protocol);
                request_.method = method;
                request_.pathname = "/";
                let globalQueries = {};
                let globalHeaders = {};
                if (!tea_util_1.default.isUnset(this._globalParameters)) {
                    let globalParams = this._globalParameters;
                    if (!tea_util_1.default.isUnset(globalParams.queries)) {
                        globalQueries = globalParams.queries;
                    }
                    if (!tea_util_1.default.isUnset(globalParams.headers)) {
                        globalHeaders = globalParams.headers;
                    }
                }
                let extendsHeaders = {};
                let extendsQueries = {};
                if (!tea_util_1.default.isUnset(runtime.extendsParameters)) {
                    let extendsParameters = runtime.extendsParameters;
                    if (!tea_util_1.default.isUnset(extendsParameters.headers)) {
                        extendsHeaders = extendsParameters.headers;
                    }
                    if (!tea_util_1.default.isUnset(extendsParameters.queries)) {
                        extendsQueries = extendsParameters.queries;
                    }
                }
                request_.query = Object.assign(Object.assign(Object.assign({ Action: action, Format: "json", Version: version, Timestamp: openapi_util_1.default.getTimestamp(), SignatureNonce: tea_util_1.default.getNonce() }, globalQueries), extendsQueries), request.query);
                let headers = this.getRpcHeaders();
                if (tea_util_1.default.isUnset(headers)) {
                    // endpoint is setted in product client
                    request_.headers = Object.assign(Object.assign(Object.assign({ host: this._endpoint, 'x-acs-version': version, 'x-acs-action': action, 'user-agent': this.getUserAgent() }, globalHeaders), extendsHeaders), request.headers);
                }
                else {
                    request_.headers = Object.assign(Object.assign(Object.assign(Object.assign({ host: this._endpoint, 'x-acs-version': version, 'x-acs-action': action, 'user-agent': this.getUserAgent() }, globalHeaders), extendsHeaders), request.headers), headers);
                }
                if (!tea_util_1.default.isUnset(request.body)) {
                    let m = tea_util_1.default.assertAsMap(request.body);
                    let tmp = tea_util_1.default.anyifyMapValue(openapi_util_1.default.query(m));
                    request_.body = new $tea.BytesReadable(tea_util_1.default.toFormString(tmp));
                    request_.headers["content-type"] = "application/x-www-form-urlencoded";
                }
                if (!tea_util_1.default.equalString(authType, "Anonymous")) {
                    if (tea_util_1.default.isUnset(this._credential)) {
                        throw $tea.newError({
                            code: `InvalidCredentials`,
                            message: `Please set up the credentials correctly. If you are setting them through environment variables, please ensure that ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set correctly. See https://help.aliyun.com/zh/sdk/developer-reference/configure-the-alibaba-cloud-accesskey-environment-variable-on-linux-macos-and-windows-systems for more details.`,
                        });
                    }
                    let credentialModel = await this._credential.getCredential();
                    if (!tea_util_1.default.empty(credentialModel.providerName)) {
                        request_.headers["x-acs-credentials-provider"] = credentialModel.providerName;
                    }
                    let credentialType = credentialModel.type;
                    if (tea_util_1.default.equalString(credentialType, "bearer")) {
                        let bearerToken = credentialModel.bearerToken;
                        request_.query["BearerToken"] = bearerToken;
                        request_.query["SignatureType"] = "BEARERTOKEN";
                    }
                    else if (tea_util_1.default.equalString(credentialType, "id_token")) {
                        let idToken = credentialModel.securityToken;
                        request_.headers["x-acs-zero-trust-idtoken"] = idToken;
                    }
                    else {
                        let accessKeyId = credentialModel.accessKeyId;
                        let accessKeySecret = credentialModel.accessKeySecret;
                        let securityToken = credentialModel.securityToken;
                        if (!tea_util_1.default.empty(securityToken)) {
                            request_.query["SecurityToken"] = securityToken;
                        }
                        request_.query["SignatureMethod"] = "HMAC-SHA1";
                        request_.query["SignatureVersion"] = "1.0";
                        request_.query["AccessKeyId"] = accessKeyId;
                        let t = null;
                        if (!tea_util_1.default.isUnset(request.body)) {
                            t = tea_util_1.default.assertAsMap(request.body);
                        }
                        let signedParam = Object.assign(Object.assign({}, request_.query), openapi_util_1.default.query(t));
                        request_.query["Signature"] = openapi_util_1.default.getRPCSignature(signedParam, request_.method, accessKeySecret);
                    }
                }
                _lastRequest = request_;
                let response_ = await $tea.doAction(request_, _runtime);
                if (tea_util_1.default.is4xx(response_.statusCode) || tea_util_1.default.is5xx(response_.statusCode)) {
                    let _res = await tea_util_1.default.readAsJSON(response_.body);
                    let err = tea_util_1.default.assertAsMap(_res);
                    let requestId = Client.defaultAny(err["RequestId"], err["requestId"]);
                    err["statusCode"] = response_.statusCode;
                    throw $tea.newError({
                        code: `${Client.defaultAny(err["Code"], err["code"])}`,
                        message: `code: ${response_.statusCode}, ${Client.defaultAny(err["Message"], err["message"])} request id: ${requestId}`,
                        data: err,
                        description: `${Client.defaultAny(err["Description"], err["description"])}`,
                        accessDeniedDetail: Client.defaultAny(err["AccessDeniedDetail"], err["accessDeniedDetail"]),
                    });
                }
                if (tea_util_1.default.equalString(bodyType, "binary")) {
                    let resp = {
                        body: response_.body,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                    return resp;
                }
                else if (tea_util_1.default.equalString(bodyType, "byte")) {
                    let byt = await tea_util_1.default.readAsBytes(response_.body);
                    return {
                        body: byt,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "string")) {
                    let str = await tea_util_1.default.readAsString(response_.body);
                    return {
                        body: str,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "json")) {
                    let obj = await tea_util_1.default.readAsJSON(response_.body);
                    let res = tea_util_1.default.assertAsMap(obj);
                    return {
                        body: res,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "array")) {
                    let arr = await tea_util_1.default.readAsJSON(response_.body);
                    return {
                        body: arr,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else {
                    return {
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
            }
            catch (ex) {
                if ($tea.isRetryable(ex)) {
                    continue;
                }
                throw ex;
            }
        }
        throw $tea.newUnretryableError(_lastRequest);
    }
    /**
     * @remarks
     * Encapsulate the request and invoke the network
     *
     * @param action - api name
     * @param version - product version
     * @param protocol - http or https
     * @param method - e.g. GET
     * @param authType - authorization type e.g. AK
     * @param pathname - pathname of every api
     * @param bodyType - response body type e.g. String
     * @param request - object of OpenApiRequest
     * @param runtime - which controls some details of call api, such as retry times
     * @returns the response
     */
    async doROARequest(action, version, protocol, method, authType, pathname, bodyType, request, runtime) {
        let _runtime = {
            timeouted: "retry",
            key: tea_util_1.default.defaultString(runtime.key, this._key),
            cert: tea_util_1.default.defaultString(runtime.cert, this._cert),
            ca: tea_util_1.default.defaultString(runtime.ca, this._ca),
            readTimeout: tea_util_1.default.defaultNumber(runtime.readTimeout, this._readTimeout),
            connectTimeout: tea_util_1.default.defaultNumber(runtime.connectTimeout, this._connectTimeout),
            httpProxy: tea_util_1.default.defaultString(runtime.httpProxy, this._httpProxy),
            httpsProxy: tea_util_1.default.defaultString(runtime.httpsProxy, this._httpsProxy),
            noProxy: tea_util_1.default.defaultString(runtime.noProxy, this._noProxy),
            socks5Proxy: tea_util_1.default.defaultString(runtime.socks5Proxy, this._socks5Proxy),
            socks5NetWork: tea_util_1.default.defaultString(runtime.socks5NetWork, this._socks5NetWork),
            maxIdleConns: tea_util_1.default.defaultNumber(runtime.maxIdleConns, this._maxIdleConns),
            retry: {
                retryable: runtime.autoretry,
                maxAttempts: tea_util_1.default.defaultNumber(runtime.maxAttempts, 3),
            },
            backoff: {
                policy: tea_util_1.default.defaultString(runtime.backoffPolicy, "no"),
                period: tea_util_1.default.defaultNumber(runtime.backoffPeriod, 1),
            },
            ignoreSSL: runtime.ignoreSSL,
            tlsMinVersion: this._tlsMinVersion,
        };
        let _lastRequest = null;
        let _now = Date.now();
        let _retryTimes = 0;
        while ($tea.allowRetry(_runtime['retry'], _retryTimes, _now)) {
            if (_retryTimes > 0) {
                let _backoffTime = $tea.getBackoffTime(_runtime['backoff'], _retryTimes);
                if (_backoffTime > 0) {
                    await $tea.sleep(_backoffTime);
                }
            }
            _retryTimes = _retryTimes + 1;
            try {
                let request_ = new $tea.Request();
                request_.protocol = tea_util_1.default.defaultString(this._protocol, protocol);
                request_.method = method;
                request_.pathname = pathname;
                let globalQueries = {};
                let globalHeaders = {};
                if (!tea_util_1.default.isUnset(this._globalParameters)) {
                    let globalParams = this._globalParameters;
                    if (!tea_util_1.default.isUnset(globalParams.queries)) {
                        globalQueries = globalParams.queries;
                    }
                    if (!tea_util_1.default.isUnset(globalParams.headers)) {
                        globalHeaders = globalParams.headers;
                    }
                }
                let extendsHeaders = {};
                let extendsQueries = {};
                if (!tea_util_1.default.isUnset(runtime.extendsParameters)) {
                    let extendsParameters = runtime.extendsParameters;
                    if (!tea_util_1.default.isUnset(extendsParameters.headers)) {
                        extendsHeaders = extendsParameters.headers;
                    }
                    if (!tea_util_1.default.isUnset(extendsParameters.queries)) {
                        extendsQueries = extendsParameters.queries;
                    }
                }
                request_.headers = Object.assign(Object.assign(Object.assign({ date: tea_util_1.default.getDateUTCString(), host: this._endpoint, accept: "application/json", 'x-acs-signature-nonce': tea_util_1.default.getNonce(), 'x-acs-signature-method': "HMAC-SHA1", 'x-acs-signature-version': "1.0", 'x-acs-version': version, 'x-acs-action': action, 'user-agent': tea_util_1.default.getUserAgent(this._userAgent) }, globalHeaders), extendsHeaders), request.headers);
                if (!tea_util_1.default.isUnset(request.body)) {
                    request_.body = new $tea.BytesReadable(tea_util_1.default.toJSONString(request.body));
                    request_.headers["content-type"] = "application/json; charset=utf-8";
                }
                request_.query = Object.assign(Object.assign({}, globalQueries), extendsQueries);
                if (!tea_util_1.default.isUnset(request.query)) {
                    request_.query = Object.assign(Object.assign({}, request_.query), request.query);
                }
                if (!tea_util_1.default.equalString(authType, "Anonymous")) {
                    if (tea_util_1.default.isUnset(this._credential)) {
                        throw $tea.newError({
                            code: `InvalidCredentials`,
                            message: `Please set up the credentials correctly. If you are setting them through environment variables, please ensure that ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set correctly. See https://help.aliyun.com/zh/sdk/developer-reference/configure-the-alibaba-cloud-accesskey-environment-variable-on-linux-macos-and-windows-systems for more details.`,
                        });
                    }
                    let credentialModel = await this._credential.getCredential();
                    if (!tea_util_1.default.empty(credentialModel.providerName)) {
                        request_.headers["x-acs-credentials-provider"] = credentialModel.providerName;
                    }
                    let credentialType = credentialModel.type;
                    if (tea_util_1.default.equalString(credentialType, "bearer")) {
                        let bearerToken = credentialModel.bearerToken;
                        request_.headers["x-acs-bearer-token"] = bearerToken;
                        request_.headers["x-acs-signature-type"] = "BEARERTOKEN";
                    }
                    else if (tea_util_1.default.equalString(credentialType, "id_token")) {
                        let idToken = credentialModel.securityToken;
                        request_.headers["x-acs-zero-trust-idtoken"] = idToken;
                    }
                    else {
                        let accessKeyId = credentialModel.accessKeyId;
                        let accessKeySecret = credentialModel.accessKeySecret;
                        let securityToken = credentialModel.securityToken;
                        if (!tea_util_1.default.empty(securityToken)) {
                            request_.headers["x-acs-accesskey-id"] = accessKeyId;
                            request_.headers["x-acs-security-token"] = securityToken;
                        }
                        let stringToSign = openapi_util_1.default.getStringToSign(request_);
                        request_.headers["authorization"] = `acs ${accessKeyId}:${openapi_util_1.default.getROASignature(stringToSign, accessKeySecret)}`;
                    }
                }
                _lastRequest = request_;
                let response_ = await $tea.doAction(request_, _runtime);
                if (tea_util_1.default.equalNumber(response_.statusCode, 204)) {
                    return {
                        headers: response_.headers,
                    };
                }
                if (tea_util_1.default.is4xx(response_.statusCode) || tea_util_1.default.is5xx(response_.statusCode)) {
                    let _res = await tea_util_1.default.readAsJSON(response_.body);
                    let err = tea_util_1.default.assertAsMap(_res);
                    let requestId = Client.defaultAny(err["RequestId"], err["requestId"]);
                    requestId = Client.defaultAny(requestId, err["requestid"]);
                    err["statusCode"] = response_.statusCode;
                    throw $tea.newError({
                        code: `${Client.defaultAny(err["Code"], err["code"])}`,
                        message: `code: ${response_.statusCode}, ${Client.defaultAny(err["Message"], err["message"])} request id: ${requestId}`,
                        data: err,
                        description: `${Client.defaultAny(err["Description"], err["description"])}`,
                        accessDeniedDetail: Client.defaultAny(err["AccessDeniedDetail"], err["accessDeniedDetail"]),
                    });
                }
                if (tea_util_1.default.equalString(bodyType, "binary")) {
                    let resp = {
                        body: response_.body,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                    return resp;
                }
                else if (tea_util_1.default.equalString(bodyType, "byte")) {
                    let byt = await tea_util_1.default.readAsBytes(response_.body);
                    return {
                        body: byt,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "string")) {
                    let str = await tea_util_1.default.readAsString(response_.body);
                    return {
                        body: str,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "json")) {
                    let obj = await tea_util_1.default.readAsJSON(response_.body);
                    let res = tea_util_1.default.assertAsMap(obj);
                    return {
                        body: res,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "array")) {
                    let arr = await tea_util_1.default.readAsJSON(response_.body);
                    return {
                        body: arr,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else {
                    return {
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
            }
            catch (ex) {
                if ($tea.isRetryable(ex)) {
                    continue;
                }
                throw ex;
            }
        }
        throw $tea.newUnretryableError(_lastRequest);
    }
    /**
     * @remarks
     * Encapsulate the request and invoke the network with form body
     *
     * @param action - api name
     * @param version - product version
     * @param protocol - http or https
     * @param method - e.g. GET
     * @param authType - authorization type e.g. AK
     * @param pathname - pathname of every api
     * @param bodyType - response body type e.g. String
     * @param request - object of OpenApiRequest
     * @param runtime - which controls some details of call api, such as retry times
     * @returns the response
     */
    async doROARequestWithForm(action, version, protocol, method, authType, pathname, bodyType, request, runtime) {
        let _runtime = {
            timeouted: "retry",
            key: tea_util_1.default.defaultString(runtime.key, this._key),
            cert: tea_util_1.default.defaultString(runtime.cert, this._cert),
            ca: tea_util_1.default.defaultString(runtime.ca, this._ca),
            readTimeout: tea_util_1.default.defaultNumber(runtime.readTimeout, this._readTimeout),
            connectTimeout: tea_util_1.default.defaultNumber(runtime.connectTimeout, this._connectTimeout),
            httpProxy: tea_util_1.default.defaultString(runtime.httpProxy, this._httpProxy),
            httpsProxy: tea_util_1.default.defaultString(runtime.httpsProxy, this._httpsProxy),
            noProxy: tea_util_1.default.defaultString(runtime.noProxy, this._noProxy),
            socks5Proxy: tea_util_1.default.defaultString(runtime.socks5Proxy, this._socks5Proxy),
            socks5NetWork: tea_util_1.default.defaultString(runtime.socks5NetWork, this._socks5NetWork),
            maxIdleConns: tea_util_1.default.defaultNumber(runtime.maxIdleConns, this._maxIdleConns),
            retry: {
                retryable: runtime.autoretry,
                maxAttempts: tea_util_1.default.defaultNumber(runtime.maxAttempts, 3),
            },
            backoff: {
                policy: tea_util_1.default.defaultString(runtime.backoffPolicy, "no"),
                period: tea_util_1.default.defaultNumber(runtime.backoffPeriod, 1),
            },
            ignoreSSL: runtime.ignoreSSL,
            tlsMinVersion: this._tlsMinVersion,
        };
        let _lastRequest = null;
        let _now = Date.now();
        let _retryTimes = 0;
        while ($tea.allowRetry(_runtime['retry'], _retryTimes, _now)) {
            if (_retryTimes > 0) {
                let _backoffTime = $tea.getBackoffTime(_runtime['backoff'], _retryTimes);
                if (_backoffTime > 0) {
                    await $tea.sleep(_backoffTime);
                }
            }
            _retryTimes = _retryTimes + 1;
            try {
                let request_ = new $tea.Request();
                request_.protocol = tea_util_1.default.defaultString(this._protocol, protocol);
                request_.method = method;
                request_.pathname = pathname;
                let globalQueries = {};
                let globalHeaders = {};
                if (!tea_util_1.default.isUnset(this._globalParameters)) {
                    let globalParams = this._globalParameters;
                    if (!tea_util_1.default.isUnset(globalParams.queries)) {
                        globalQueries = globalParams.queries;
                    }
                    if (!tea_util_1.default.isUnset(globalParams.headers)) {
                        globalHeaders = globalParams.headers;
                    }
                }
                let extendsHeaders = {};
                let extendsQueries = {};
                if (!tea_util_1.default.isUnset(runtime.extendsParameters)) {
                    let extendsParameters = runtime.extendsParameters;
                    if (!tea_util_1.default.isUnset(extendsParameters.headers)) {
                        extendsHeaders = extendsParameters.headers;
                    }
                    if (!tea_util_1.default.isUnset(extendsParameters.queries)) {
                        extendsQueries = extendsParameters.queries;
                    }
                }
                request_.headers = Object.assign(Object.assign(Object.assign({ date: tea_util_1.default.getDateUTCString(), host: this._endpoint, accept: "application/json", 'x-acs-signature-nonce': tea_util_1.default.getNonce(), 'x-acs-signature-method': "HMAC-SHA1", 'x-acs-signature-version': "1.0", 'x-acs-version': version, 'x-acs-action': action, 'user-agent': tea_util_1.default.getUserAgent(this._userAgent) }, globalHeaders), extendsHeaders), request.headers);
                if (!tea_util_1.default.isUnset(request.body)) {
                    let m = tea_util_1.default.assertAsMap(request.body);
                    request_.body = new $tea.BytesReadable(openapi_util_1.default.toForm(m));
                    request_.headers["content-type"] = "application/x-www-form-urlencoded";
                }
                request_.query = Object.assign(Object.assign({}, globalQueries), extendsQueries);
                if (!tea_util_1.default.isUnset(request.query)) {
                    request_.query = Object.assign(Object.assign({}, request_.query), request.query);
                }
                if (!tea_util_1.default.equalString(authType, "Anonymous")) {
                    if (tea_util_1.default.isUnset(this._credential)) {
                        throw $tea.newError({
                            code: `InvalidCredentials`,
                            message: `Please set up the credentials correctly. If you are setting them through environment variables, please ensure that ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set correctly. See https://help.aliyun.com/zh/sdk/developer-reference/configure-the-alibaba-cloud-accesskey-environment-variable-on-linux-macos-and-windows-systems for more details.`,
                        });
                    }
                    let credentialModel = await this._credential.getCredential();
                    if (!tea_util_1.default.empty(credentialModel.providerName)) {
                        request_.headers["x-acs-credentials-provider"] = credentialModel.providerName;
                    }
                    let credentialType = credentialModel.type;
                    if (tea_util_1.default.equalString(credentialType, "bearer")) {
                        let bearerToken = credentialModel.bearerToken;
                        request_.headers["x-acs-bearer-token"] = bearerToken;
                        request_.headers["x-acs-signature-type"] = "BEARERTOKEN";
                    }
                    else if (tea_util_1.default.equalString(credentialType, "id_token")) {
                        let idToken = credentialModel.securityToken;
                        request_.headers["x-acs-zero-trust-idtoken"] = idToken;
                    }
                    else {
                        let accessKeyId = credentialModel.accessKeyId;
                        let accessKeySecret = credentialModel.accessKeySecret;
                        let securityToken = credentialModel.securityToken;
                        if (!tea_util_1.default.empty(securityToken)) {
                            request_.headers["x-acs-accesskey-id"] = accessKeyId;
                            request_.headers["x-acs-security-token"] = securityToken;
                        }
                        let stringToSign = openapi_util_1.default.getStringToSign(request_);
                        request_.headers["authorization"] = `acs ${accessKeyId}:${openapi_util_1.default.getROASignature(stringToSign, accessKeySecret)}`;
                    }
                }
                _lastRequest = request_;
                let response_ = await $tea.doAction(request_, _runtime);
                if (tea_util_1.default.equalNumber(response_.statusCode, 204)) {
                    return {
                        headers: response_.headers,
                    };
                }
                if (tea_util_1.default.is4xx(response_.statusCode) || tea_util_1.default.is5xx(response_.statusCode)) {
                    let _res = await tea_util_1.default.readAsJSON(response_.body);
                    let err = tea_util_1.default.assertAsMap(_res);
                    err["statusCode"] = response_.statusCode;
                    throw $tea.newError({
                        code: `${Client.defaultAny(err["Code"], err["code"])}`,
                        message: `code: ${response_.statusCode}, ${Client.defaultAny(err["Message"], err["message"])} request id: ${Client.defaultAny(err["RequestId"], err["requestId"])}`,
                        data: err,
                        description: `${Client.defaultAny(err["Description"], err["description"])}`,
                        accessDeniedDetail: Client.defaultAny(err["AccessDeniedDetail"], err["accessDeniedDetail"]),
                    });
                }
                if (tea_util_1.default.equalString(bodyType, "binary")) {
                    let resp = {
                        body: response_.body,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                    return resp;
                }
                else if (tea_util_1.default.equalString(bodyType, "byte")) {
                    let byt = await tea_util_1.default.readAsBytes(response_.body);
                    return {
                        body: byt,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "string")) {
                    let str = await tea_util_1.default.readAsString(response_.body);
                    return {
                        body: str,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "json")) {
                    let obj = await tea_util_1.default.readAsJSON(response_.body);
                    let res = tea_util_1.default.assertAsMap(obj);
                    return {
                        body: res,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(bodyType, "array")) {
                    let arr = await tea_util_1.default.readAsJSON(response_.body);
                    return {
                        body: arr,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else {
                    return {
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
            }
            catch (ex) {
                if ($tea.isRetryable(ex)) {
                    continue;
                }
                throw ex;
            }
        }
        throw $tea.newUnretryableError(_lastRequest);
    }
    /**
     * @remarks
     * Encapsulate the request and invoke the network
     *
     * @param action - api name
     * @param version - product version
     * @param protocol - http or https
     * @param method - e.g. GET
     * @param authType - authorization type e.g. AK
     * @param bodyType - response body type e.g. String
     * @param request - object of OpenApiRequest
     * @param runtime - which controls some details of call api, such as retry times
     * @returns the response
     */
    async doRequest(params, request, runtime) {
        let _runtime = {
            timeouted: "retry",
            key: tea_util_1.default.defaultString(runtime.key, this._key),
            cert: tea_util_1.default.defaultString(runtime.cert, this._cert),
            ca: tea_util_1.default.defaultString(runtime.ca, this._ca),
            readTimeout: tea_util_1.default.defaultNumber(runtime.readTimeout, this._readTimeout),
            connectTimeout: tea_util_1.default.defaultNumber(runtime.connectTimeout, this._connectTimeout),
            httpProxy: tea_util_1.default.defaultString(runtime.httpProxy, this._httpProxy),
            httpsProxy: tea_util_1.default.defaultString(runtime.httpsProxy, this._httpsProxy),
            noProxy: tea_util_1.default.defaultString(runtime.noProxy, this._noProxy),
            socks5Proxy: tea_util_1.default.defaultString(runtime.socks5Proxy, this._socks5Proxy),
            socks5NetWork: tea_util_1.default.defaultString(runtime.socks5NetWork, this._socks5NetWork),
            maxIdleConns: tea_util_1.default.defaultNumber(runtime.maxIdleConns, this._maxIdleConns),
            retry: {
                retryable: runtime.autoretry,
                maxAttempts: tea_util_1.default.defaultNumber(runtime.maxAttempts, 3),
            },
            backoff: {
                policy: tea_util_1.default.defaultString(runtime.backoffPolicy, "no"),
                period: tea_util_1.default.defaultNumber(runtime.backoffPeriod, 1),
            },
            ignoreSSL: runtime.ignoreSSL,
            tlsMinVersion: this._tlsMinVersion,
        };
        let _lastRequest = null;
        let _now = Date.now();
        let _retryTimes = 0;
        while ($tea.allowRetry(_runtime['retry'], _retryTimes, _now)) {
            if (_retryTimes > 0) {
                let _backoffTime = $tea.getBackoffTime(_runtime['backoff'], _retryTimes);
                if (_backoffTime > 0) {
                    await $tea.sleep(_backoffTime);
                }
            }
            _retryTimes = _retryTimes + 1;
            try {
                let request_ = new $tea.Request();
                request_.protocol = tea_util_1.default.defaultString(this._protocol, params.protocol);
                request_.method = params.method;
                request_.pathname = params.pathname;
                let globalQueries = {};
                let globalHeaders = {};
                if (!tea_util_1.default.isUnset(this._globalParameters)) {
                    let globalParams = this._globalParameters;
                    if (!tea_util_1.default.isUnset(globalParams.queries)) {
                        globalQueries = globalParams.queries;
                    }
                    if (!tea_util_1.default.isUnset(globalParams.headers)) {
                        globalHeaders = globalParams.headers;
                    }
                }
                let extendsHeaders = {};
                let extendsQueries = {};
                if (!tea_util_1.default.isUnset(runtime.extendsParameters)) {
                    let extendsParameters = runtime.extendsParameters;
                    if (!tea_util_1.default.isUnset(extendsParameters.headers)) {
                        extendsHeaders = extendsParameters.headers;
                    }
                    if (!tea_util_1.default.isUnset(extendsParameters.queries)) {
                        extendsQueries = extendsParameters.queries;
                    }
                }
                request_.query = Object.assign(Object.assign(Object.assign({}, globalQueries), extendsQueries), request.query);
                // endpoint is setted in product client
                request_.headers = Object.assign(Object.assign(Object.assign({ host: this._endpoint, 'x-acs-version': params.version, 'x-acs-action': params.action, 'user-agent': this.getUserAgent(), 'x-acs-date': openapi_util_1.default.getTimestamp(), 'x-acs-signature-nonce': tea_util_1.default.getNonce(), accept: "application/json" }, globalHeaders), extendsHeaders), request.headers);
                if (tea_util_1.default.equalString(params.style, "RPC")) {
                    let headers = this.getRpcHeaders();
                    if (!tea_util_1.default.isUnset(headers)) {
                        request_.headers = Object.assign(Object.assign({}, request_.headers), headers);
                    }
                }
                let signatureAlgorithm = tea_util_1.default.defaultString(this._signatureAlgorithm, "ACS3-HMAC-SHA256");
                let hashedRequestPayload = openapi_util_1.default.hexEncode(openapi_util_1.default.hash(tea_util_1.default.toBytes(""), signatureAlgorithm));
                if (!tea_util_1.default.isUnset(request.stream)) {
                    let tmp = await tea_util_1.default.readAsBytes(request.stream);
                    hashedRequestPayload = openapi_util_1.default.hexEncode(openapi_util_1.default.hash(tmp, signatureAlgorithm));
                    request_.body = new $tea.BytesReadable(tmp);
                    request_.headers["content-type"] = "application/octet-stream";
                }
                else {
                    if (!tea_util_1.default.isUnset(request.body)) {
                        if (tea_util_1.default.equalString(params.reqBodyType, "byte")) {
                            let byteObj = tea_util_1.default.assertAsBytes(request.body);
                            hashedRequestPayload = openapi_util_1.default.hexEncode(openapi_util_1.default.hash(byteObj, signatureAlgorithm));
                            request_.body = new $tea.BytesReadable(byteObj);
                        }
                        else if (tea_util_1.default.equalString(params.reqBodyType, "json")) {
                            let jsonObj = tea_util_1.default.toJSONString(request.body);
                            hashedRequestPayload = openapi_util_1.default.hexEncode(openapi_util_1.default.hash(tea_util_1.default.toBytes(jsonObj), signatureAlgorithm));
                            request_.body = new $tea.BytesReadable(jsonObj);
                            request_.headers["content-type"] = "application/json; charset=utf-8";
                        }
                        else {
                            let m = tea_util_1.default.assertAsMap(request.body);
                            let formObj = openapi_util_1.default.toForm(m);
                            hashedRequestPayload = openapi_util_1.default.hexEncode(openapi_util_1.default.hash(tea_util_1.default.toBytes(formObj), signatureAlgorithm));
                            request_.body = new $tea.BytesReadable(formObj);
                            request_.headers["content-type"] = "application/x-www-form-urlencoded";
                        }
                    }
                }
                request_.headers["x-acs-content-sha256"] = hashedRequestPayload;
                if (!tea_util_1.default.equalString(params.authType, "Anonymous")) {
                    if (tea_util_1.default.isUnset(this._credential)) {
                        throw $tea.newError({
                            code: `InvalidCredentials`,
                            message: `Please set up the credentials correctly. If you are setting them through environment variables, please ensure that ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set correctly. See https://help.aliyun.com/zh/sdk/developer-reference/configure-the-alibaba-cloud-accesskey-environment-variable-on-linux-macos-and-windows-systems for more details.`,
                        });
                    }
                    let credentialModel = await this._credential.getCredential();
                    if (!tea_util_1.default.empty(credentialModel.providerName)) {
                        request_.headers["x-acs-credentials-provider"] = credentialModel.providerName;
                    }
                    let authType = credentialModel.type;
                    if (tea_util_1.default.equalString(authType, "bearer")) {
                        let bearerToken = credentialModel.bearerToken;
                        request_.headers["x-acs-bearer-token"] = bearerToken;
                        if (tea_util_1.default.equalString(params.style, "RPC")) {
                            request_.query["SignatureType"] = "BEARERTOKEN";
                        }
                        else {
                            request_.headers["x-acs-signature-type"] = "BEARERTOKEN";
                        }
                    }
                    else if (tea_util_1.default.equalString(authType, "id_token")) {
                        let idToken = credentialModel.securityToken;
                        request_.headers["x-acs-zero-trust-idtoken"] = idToken;
                    }
                    else {
                        let accessKeyId = credentialModel.accessKeyId;
                        let accessKeySecret = credentialModel.accessKeySecret;
                        let securityToken = credentialModel.securityToken;
                        if (!tea_util_1.default.empty(securityToken)) {
                            request_.headers["x-acs-accesskey-id"] = accessKeyId;
                            request_.headers["x-acs-security-token"] = securityToken;
                        }
                        request_.headers["Authorization"] = openapi_util_1.default.getAuthorization(request_, signatureAlgorithm, hashedRequestPayload, accessKeyId, accessKeySecret);
                    }
                }
                _lastRequest = request_;
                let response_ = await $tea.doAction(request_, _runtime);
                if (tea_util_1.default.is4xx(response_.statusCode) || tea_util_1.default.is5xx(response_.statusCode)) {
                    let err = {};
                    if (!tea_util_1.default.isUnset(response_.headers["content-type"]) && tea_util_1.default.equalString(response_.headers["content-type"], "text/xml;charset=utf-8")) {
                        let _str = await tea_util_1.default.readAsString(response_.body);
                        let respMap = tea_xml_1.default.parseXml(_str, null);
                        err = tea_util_1.default.assertAsMap(respMap["Error"]);
                    }
                    else {
                        let _res = await tea_util_1.default.readAsJSON(response_.body);
                        err = tea_util_1.default.assertAsMap(_res);
                    }
                    err["statusCode"] = response_.statusCode;
                    throw $tea.newError({
                        code: `${Client.defaultAny(err["Code"], err["code"])}`,
                        message: `code: ${response_.statusCode}, ${Client.defaultAny(err["Message"], err["message"])} request id: ${Client.defaultAny(err["RequestId"], err["requestId"])}`,
                        data: err,
                        description: `${Client.defaultAny(err["Description"], err["description"])}`,
                        accessDeniedDetail: Client.defaultAny(err["AccessDeniedDetail"], err["accessDeniedDetail"]),
                    });
                }
                if (tea_util_1.default.equalString(params.bodyType, "binary")) {
                    let resp = {
                        body: response_.body,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                    return resp;
                }
                else if (tea_util_1.default.equalString(params.bodyType, "byte")) {
                    let byt = await tea_util_1.default.readAsBytes(response_.body);
                    return {
                        body: byt,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(params.bodyType, "string")) {
                    let str = await tea_util_1.default.readAsString(response_.body);
                    return {
                        body: str,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(params.bodyType, "json")) {
                    let obj = await tea_util_1.default.readAsJSON(response_.body);
                    let res = tea_util_1.default.assertAsMap(obj);
                    return {
                        body: res,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else if (tea_util_1.default.equalString(params.bodyType, "array")) {
                    let arr = await tea_util_1.default.readAsJSON(response_.body);
                    return {
                        body: arr,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
                else {
                    let anything = await tea_util_1.default.readAsString(response_.body);
                    return {
                        body: anything,
                        headers: response_.headers,
                        statusCode: response_.statusCode,
                    };
                }
            }
            catch (ex) {
                if ($tea.isRetryable(ex)) {
                    continue;
                }
                throw ex;
            }
        }
        throw $tea.newUnretryableError(_lastRequest);
    }
    /**
     * @remarks
     * Encapsulate the request and invoke the network
     *
     * @param action - api name
     * @param version - product version
     * @param protocol - http or https
     * @param method - e.g. GET
     * @param authType - authorization type e.g. AK
     * @param bodyType - response body type e.g. String
     * @param request - object of OpenApiRequest
     * @param runtime - which controls some details of call api, such as retry times
     * @returns the response
     */
    async execute(params, request, runtime) {
        let _runtime = {
            timeouted: "retry",
            key: tea_util_1.default.defaultString(runtime.key, this._key),
            cert: tea_util_1.default.defaultString(runtime.cert, this._cert),
            ca: tea_util_1.default.defaultString(runtime.ca, this._ca),
            readTimeout: tea_util_1.default.defaultNumber(runtime.readTimeout, this._readTimeout),
            connectTimeout: tea_util_1.default.defaultNumber(runtime.connectTimeout, this._connectTimeout),
            httpProxy: tea_util_1.default.defaultString(runtime.httpProxy, this._httpProxy),
            httpsProxy: tea_util_1.default.defaultString(runtime.httpsProxy, this._httpsProxy),
            noProxy: tea_util_1.default.defaultString(runtime.noProxy, this._noProxy),
            socks5Proxy: tea_util_1.default.defaultString(runtime.socks5Proxy, this._socks5Proxy),
            socks5NetWork: tea_util_1.default.defaultString(runtime.socks5NetWork, this._socks5NetWork),
            maxIdleConns: tea_util_1.default.defaultNumber(runtime.maxIdleConns, this._maxIdleConns),
            retry: {
                retryable: runtime.autoretry,
                maxAttempts: tea_util_1.default.defaultNumber(runtime.maxAttempts, 3),
            },
            backoff: {
                policy: tea_util_1.default.defaultString(runtime.backoffPolicy, "no"),
                period: tea_util_1.default.defaultNumber(runtime.backoffPeriod, 1),
            },
            ignoreSSL: runtime.ignoreSSL,
            disableHttp2: Client.defaultAny(this._disableHttp2, false),
            tlsMinVersion: this._tlsMinVersion,
        };
        let _lastRequest = null;
        let _now = Date.now();
        let _retryTimes = 0;
        while ($tea.allowRetry(_runtime['retry'], _retryTimes, _now)) {
            if (_retryTimes > 0) {
                let _backoffTime = $tea.getBackoffTime(_runtime['backoff'], _retryTimes);
                if (_backoffTime > 0) {
                    await $tea.sleep(_backoffTime);
                }
            }
            _retryTimes = _retryTimes + 1;
            try {
                let request_ = new $tea.Request();
                // spi = new Gateway();//Gateway implements SPI，这一步在产品 SDK 中实例化
                let headers = this.getRpcHeaders();
                let globalQueries = {};
                let globalHeaders = {};
                if (!tea_util_1.default.isUnset(this._globalParameters)) {
                    let globalParams = this._globalParameters;
                    if (!tea_util_1.default.isUnset(globalParams.queries)) {
                        globalQueries = globalParams.queries;
                    }
                    if (!tea_util_1.default.isUnset(globalParams.headers)) {
                        globalHeaders = globalParams.headers;
                    }
                }
                let extendsHeaders = {};
                let extendsQueries = {};
                if (!tea_util_1.default.isUnset(runtime.extendsParameters)) {
                    let extendsParameters = runtime.extendsParameters;
                    if (!tea_util_1.default.isUnset(extendsParameters.headers)) {
                        extendsHeaders = extendsParameters.headers;
                    }
                    if (!tea_util_1.default.isUnset(extendsParameters.queries)) {
                        extendsQueries = extendsParameters.queries;
                    }
                }
                let requestContext = new $SPI.InterceptorContextRequest({
                    headers: Object.assign(Object.assign(Object.assign(Object.assign({}, globalHeaders), extendsHeaders), request.headers), headers),
                    query: Object.assign(Object.assign(Object.assign({}, globalQueries), extendsQueries), request.query),
                    body: request.body,
                    stream: request.stream,
                    hostMap: request.hostMap,
                    pathname: params.pathname,
                    productId: this._productId,
                    action: params.action,
                    version: params.version,
                    protocol: tea_util_1.default.defaultString(this._protocol, params.protocol),
                    method: tea_util_1.default.defaultString(this._method, params.method),
                    authType: params.authType,
                    bodyType: params.bodyType,
                    reqBodyType: params.reqBodyType,
                    style: params.style,
                    credential: this._credential,
                    signatureVersion: this._signatureVersion,
                    signatureAlgorithm: this._signatureAlgorithm,
                    userAgent: this.getUserAgent(),
                });
                let configurationContext = new $SPI.InterceptorContextConfiguration({
                    regionId: this._regionId,
                    endpoint: tea_util_1.default.defaultString(request.endpointOverride, this._endpoint),
                    endpointRule: this._endpointRule,
                    endpointMap: this._endpointMap,
                    endpointType: this._endpointType,
                    network: this._network,
                    suffix: this._suffix,
                });
                let interceptorContext = new $SPI.InterceptorContext({});
                interceptorContext.request = requestContext;
                interceptorContext.configuration = configurationContext;
                let attributeMap = new $SPI.AttributeMap({});
                if (!tea_util_1.default.isUnset(this._attributeMap)) {
                    attributeMap = this._attributeMap;
                }
                // 1. spi.modifyConfiguration(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap);
                await this._spi.modifyConfiguration(interceptorContext, attributeMap);
                // 2. spi.modifyRequest(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap);
                await this._spi.modifyRequest(interceptorContext, attributeMap);
                request_.protocol = interceptorContext.request.protocol;
                request_.method = interceptorContext.request.method;
                request_.pathname = interceptorContext.request.pathname;
                request_.query = interceptorContext.request.query;
                request_.body = interceptorContext.request.stream;
                request_.headers = interceptorContext.request.headers;
                _lastRequest = request_;
                let response_ = await $tea.doAction(request_, _runtime);
                let responseContext = new $SPI.InterceptorContextResponse({
                    statusCode: response_.statusCode,
                    headers: response_.headers,
                    body: response_.body,
                });
                interceptorContext.response = responseContext;
                // 3. spi.modifyResponse(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap);
                await this._spi.modifyResponse(interceptorContext, attributeMap);
                return {
                    headers: interceptorContext.response.headers,
                    statusCode: interceptorContext.response.statusCode,
                    body: interceptorContext.response.deserializedBody,
                };
            }
            catch (ex) {
                if ($tea.isRetryable(ex)) {
                    continue;
                }
                throw ex;
            }
        }
        throw $tea.newUnretryableError(_lastRequest);
    }
    async callApi(params, request, runtime) {
        if (tea_util_1.default.isUnset(params)) {
            throw $tea.newError({
                code: "ParameterMissing",
                message: "'params' can not be unset",
            });
        }
        if (tea_util_1.default.isUnset(this._signatureVersion) || !tea_util_1.default.equalString(this._signatureVersion, "v4")) {
            if (tea_util_1.default.isUnset(this._signatureAlgorithm) || !tea_util_1.default.equalString(this._signatureAlgorithm, "v2")) {
                return await this.doRequest(params, request, runtime);
            }
            else if (tea_util_1.default.equalString(params.style, "ROA") && tea_util_1.default.equalString(params.reqBodyType, "json")) {
                return await this.doROARequest(params.action, params.version, params.protocol, params.method, params.authType, params.pathname, params.bodyType, request, runtime);
            }
            else if (tea_util_1.default.equalString(params.style, "ROA")) {
                return await this.doROARequestWithForm(params.action, params.version, params.protocol, params.method, params.authType, params.pathname, params.bodyType, request, runtime);
            }
            else {
                return await this.doRPCRequest(params.action, params.version, params.protocol, params.method, params.authType, params.bodyType, request, runtime);
            }
        }
        else {
            return await this.execute(params, request, runtime);
        }
    }
    /**
     * @remarks
     * Get user agent
     * @returns user agent
     */
    getUserAgent() {
        let userAgent = tea_util_1.default.getUserAgent(this._userAgent);
        return userAgent;
    }
    /**
     * @remarks
     * Get accesskey id by using credential
     * @returns accesskey id
     */
    async getAccessKeyId() {
        if (tea_util_1.default.isUnset(this._credential)) {
            return "";
        }
        let accessKeyId = await this._credential.getAccessKeyId();
        return accessKeyId;
    }
    /**
     * @remarks
     * Get accesskey secret by using credential
     * @returns accesskey secret
     */
    async getAccessKeySecret() {
        if (tea_util_1.default.isUnset(this._credential)) {
            return "";
        }
        let secret = await this._credential.getAccessKeySecret();
        return secret;
    }
    /**
     * @remarks
     * Get security token by using credential
     * @returns security token
     */
    async getSecurityToken() {
        if (tea_util_1.default.isUnset(this._credential)) {
            return "";
        }
        let token = await this._credential.getSecurityToken();
        return token;
    }
    /**
     * @remarks
     * Get bearer token by credential
     * @returns bearer token
     */
    async getBearerToken() {
        if (tea_util_1.default.isUnset(this._credential)) {
            return "";
        }
        let token = this._credential.getBearerToken();
        return token;
    }
    /**
     * @remarks
     * Get credential type by credential
     * @returns credential type e.g. access_key
     */
    async getType() {
        if (tea_util_1.default.isUnset(this._credential)) {
            return "";
        }
        let authType = this._credential.getType();
        return authType;
    }
    /**
     * @remarks
     * If inputValue is not null, return it or return defaultValue
     *
     * @param inputValue - users input value
     * @param defaultValue - default value
     * @returns the final result
     */
    static defaultAny(inputValue, defaultValue) {
        if (tea_util_1.default.isUnset(inputValue)) {
            return defaultValue;
        }
        return inputValue;
    }
    /**
     * @remarks
     * If the endpointRule and config.endpoint are empty, throw error
     *
     * @param config - config contains the necessary information to create a client
     */
    checkConfig(config) {
        if (tea_util_1.default.empty(this._endpointRule) && tea_util_1.default.empty(config.endpoint)) {
            throw $tea.newError({
                code: "ParameterMissing",
                message: "'config.endpoint' can not be empty",
            });
        }
    }
    /**
     * @remarks
     * set gateway client
     *
     * @param spi - .
     */
    setGatewayClient(spi) {
        this._spi = spi;
    }
    /**
     * @remarks
     * set RPC header for debug
     *
     * @param headers - headers for debug, this header can be used only once.
     */
    setRpcHeaders(headers) {
        this._headers = headers;
    }
    /**
     * @remarks
     * get RPC header for debug
     */
    getRpcHeaders() {
        let headers = this._headers;
        this._headers = null;
        return headers;
    }
}
exports.default = Client;
//# sourceMappingURL=client.js.map