"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.remoteRef = remoteRef;
exports.makeRemoteObjectAPI = makeRemoteObjectAPI;
exports.$makeRemoteObjectAPI = $makeRemoteObjectAPI;
const Async_1 = require("../types/interface/async/Async");
const wrapper_1 = require("../types/interface/async/wrapper");
const method_1 = require("./method");
function remoteRef(ref) {
    let _ref = {};
    for (const name in ref) {
        const method = ref[name];
        const _method = (data) => {
            const { __ = [] } = data;
            data.__ = data.__ ?? [];
            const $obj = method(data);
            if (!$obj) {
                return;
            }
            const remoteApi = {
                get: {},
                call: {},
                watch: {},
                ref: {},
            };
            for (const _ of ['$', ...__]) {
                const methods = method_1.METHOD[_];
                for (const type in methods) {
                    const methodList = methods[type];
                    for (const methodName of methodList) {
                        const $methodName = `$${methodName}`;
                        if (type === 'ref') {
                            remoteApi[type][$methodName] = (...args) => {
                                let result = $obj[$methodName](...args);
                                if (result === null) {
                                    return null;
                                }
                                result = makeRemoteObjectAPI(result, result.$__ ?? result.__);
                                return result;
                            };
                        }
                        else {
                            remoteApi[type][$methodName] = $obj[$methodName];
                        }
                    }
                }
            }
            return remoteApi;
        };
        _ref[name] = _method;
    }
    return _ref;
}
function makeRemoteObjectAPI(obj, _) {
    const $unit = (0, Async_1.Async)(obj, _, wrapper_1.ASYNC);
    return $makeRemoteObjectAPI($unit, _);
}
function $makeRemoteObjectAPI($obj, _) {
    const api = {
        get: {},
        call: {},
        watch: {},
        ref: {},
    };
    for (const __ of ['$', ..._]) {
        const method = method_1.METHOD[__];
        for (const type of method_1.METHOD_TYPES) {
            for (const name of method[type]) {
                const $name = `$${name}`;
                api[type] = { ...api[type], [$name]: $obj[$name] };
            }
        }
    }
    api.ref = remoteRef(api.ref);
    return api;
}
//# sourceMappingURL=makeRemoteUnitAPI.js.map