/*!
 * TSRPC Miniapp v3.4.16
 * -----------------------------------------
 * Copyright (c) King Wang.
 * MIT License
 * https://github.com/k8w/tsrpc-miniapp
 */
import 'k8w-extend-native';
import { __extends, __assign } from 'tslib';
import { BaseHttpClient, defaultBaseHttpClientOptions, BaseWsClient, defaultBaseWsClientOptions } from 'tsrpc-base-client';
import { TsrpcError } from 'tsrpc-proto';
export * from 'tsrpc-proto';

var HttpProxy = /** @class */ (function () {
    function HttpProxy() {
    }
    HttpProxy.prototype.fetch = function (options) {
        var _a;
        if (!this.miniappObj) {
            return {
                abort: function () { },
                promise: Promise.resolve({
                    isSucc: false,
                    err: new TsrpcError('miniappObj is not set, please check if this is miniapp environment.', { type: TsrpcError.Type.ClientError })
                })
            };
        }
        var rs;
        var promise = new Promise(function (_rs) {
            rs = _rs;
        });
        var data;
        if (typeof options.data === 'string') {
            data = options.data;
        }
        else {
            var buf = options.data;
            if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
                data = buf.buffer;
            }
            else {
                data = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
            }
        }
        var reqTask = this.miniappObj.request({
            url: options.url,
            data: data,
            method: options.method,
            header: (_a = options.headers) !== null && _a !== void 0 ? _a : {
                'content-type': 'application/octet-stream'
            },
            dataType: '其他',
            responseType: options.responseType,
            success: function (res) {
                if (res.statusCode === 200 || res.statusCode === 500) {
                    rs({
                        isSucc: true,
                        res: typeof res.data === 'string' ? res.data : new Uint8Array(res.data)
                    });
                }
                else {
                    rs({
                        isSucc: false,
                        err: new TsrpcError({
                            message: 'HTTP Error ' + res.statusCode,
                            type: TsrpcError.Type.ServerError,
                            httpCode: res.statusCode
                        })
                    });
                }
            },
            fail: function (res) {
                rs({
                    isSucc: false,
                    err: new TsrpcError({
                        message: 'Network Error',
                        type: TsrpcError.Type.NetworkError,
                        innerErr: res
                    })
                });
            }
        });
        var abort = reqTask.abort.bind(reqTask);
        return {
            promise: promise,
            abort: abort
        };
    };
    return HttpProxy;
}());

/**
 * Client for TSRPC HTTP Server.
 * It uses native http module of NodeJS.
 * @typeParam ServiceType - `ServiceType` from generated `proto.ts`
 */
var HttpClient = /** @class */ (function (_super) {
    __extends(HttpClient, _super);
    function HttpClient(proto, options) {
        var _this = this;
        var httpProxy = new HttpProxy;
        _this = _super.call(this, proto, httpProxy, __assign(__assign({}, defaultHttpClientOptions), options)) || this;
        httpProxy.miniappObj = _this.options.miniappObj;
        return _this;
    }
    return HttpClient;
}(BaseHttpClient));
var defaultHttpClientOptions = __assign(__assign({}, defaultBaseHttpClientOptions), { miniappObj: typeof wx !== 'undefined' ? wx : undefined, customObjectIdClass: String });

var WebSocketProxy = /** @class */ (function () {
    function WebSocketProxy() {
    }
    WebSocketProxy.prototype.connect = function (server, protocols) {
        var _this = this;
        var ws = this.miniappObj.connectSocket(__assign(__assign({}, this.client.options.connectSocketOptions), { url: server, protocols: protocols }));
        this._ws = ws;
        this._ws.onOpen(function (header) {
            if (_this._ws !== ws) {
                return;
            }
            _this.options.onOpen();
        });
        this._ws.onError(function (res) {
            if (_this._ws !== ws) {
                return;
            }
            ws.close();
            _this._ws = undefined;
            _this.options.onError(res);
        });
        this._ws.onClose(function (e) {
            if (_this._ws !== ws) {
                return;
            }
            _this._ws = undefined;
            _this.options.onClose(e.code, e.reason);
        });
        this._ws.onMessage(function (e) {
            if (_this._ws !== ws) {
                return;
            }
            if (typeof e.data === 'string') {
                _this.options.onMessage(e.data);
            }
            else {
                _this.options.onMessage(new Uint8Array(e.data));
            }
        });
    };
    WebSocketProxy.prototype.close = function (code, reason) {
        var _this = this;
        var _a;
        (_a = this._ws) === null || _a === void 0 ? void 0 : _a.close({
            code: code,
            reason: reason,
            fail: function (res) {
                var _a;
                // 重试一次
                console.error('WebSocket closed failed', res);
                (_a = _this._ws) === null || _a === void 0 ? void 0 : _a.close();
            }
        });
        this._ws = undefined;
    };
    WebSocketProxy.prototype.send = function (data) {
        var _this = this;
        var sendData;
        if (typeof data === 'string') {
            sendData = data;
        }
        else {
            var buf = data;
            if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
                sendData = buf.buffer;
            }
            else {
                sendData = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
            }
        }
        return new Promise(function (rs) {
            _this._ws.send({
                data: sendData,
                success: function () { rs({}); },
                fail: function (res) {
                    rs({
                        err: new TsrpcError({
                            message: 'Network Error',
                            type: TsrpcError.Type.NetworkError,
                            innerErr: res
                        })
                    });
                }
            });
        });
    };
    return WebSocketProxy;
}());

/**
 * Client for TSRPC WebSocket Server.
 * @typeParam ServiceType - `ServiceType` from generated `proto.ts`
 */
var WsClient = /** @class */ (function (_super) {
    __extends(WsClient, _super);
    function WsClient(proto, options) {
        var _this = this;
        var wsp = new WebSocketProxy();
        _this = _super.call(this, proto, wsp, __assign(__assign({}, defaultWsClientOptions), options)) || this;
        if (!_this.options.miniappObj) {
            throw new Error('options.miniappObj is not set');
        }
        wsp.miniappObj = _this.options.miniappObj;
        wsp.client = _this;
        return _this;
    }
    return WsClient;
}(BaseWsClient));
var defaultWsClientOptions = __assign(__assign({}, defaultBaseWsClientOptions), { miniappObj: typeof wx !== 'undefined' ? wx : undefined, customObjectIdClass: String });

export { HttpClient, WsClient };
