import { routes } from "@lodestar/api";
import { ClientCode } from "../../../execution/index.js";
import { getLodestarClientVersion } from "../../../util/metadata.js";
import { ApiError } from "../errors.js";
export function getNodeApi(opts, { network, sync, chain }) {
    return {
        async getNetworkIdentity() {
            return {
                data: await network.getNetworkIdentity(),
            };
        },
        async getPeer({ peerId }) {
            const peer = await network.dumpPeer(peerId);
            if (!peer) {
                throw new ApiError(404, "Node has not seen this peer");
            }
            return { data: peer };
        },
        async getPeers({ state, direction }) {
            const peers = (await network.dumpPeers()).filter((nodePeer) => (!state || state.length === 0 || state.includes(nodePeer.state)) &&
                (!direction || direction.length === 0 || (nodePeer.direction && direction.includes(nodePeer.direction))));
            return {
                data: peers,
                meta: { count: peers.length },
            };
        },
        async getPeerCount() {
            // TODO: Implement disconnect count with on-disk persistence
            const data = {
                disconnected: 0,
                connecting: 0,
                connected: 0,
                disconnecting: 0,
            };
            for (const peer of await network.dumpPeers()) {
                data[peer.state]++;
            }
            return {
                data,
            };
        },
        async getNodeVersion() {
            return {
                data: {
                    version: `Lodestar/${opts.version || "dev"}`,
                },
            };
        },
        async getNodeVersionV2() {
            const { clientVersion } = chain.executionEngine;
            return {
                data: {
                    beaconNode: toSpecClientVersion(getLodestarClientVersion(opts)),
                    executionClient: clientVersion != null && clientVersion.code !== ClientCode.XX
                        ? toSpecClientVersion(clientVersion)
                        : undefined,
                },
            };
        },
        async getSyncingStatus() {
            return { data: sync.getSyncStatus() };
        },
        async getHealth({ syncingStatus }) {
            if (syncingStatus != null && (syncingStatus < 100 || syncingStatus > 599)) {
                throw new ApiError(400, `Invalid syncing status code: ${syncingStatus}`);
            }
            const { isSyncing, isOptimistic, elOffline } = sync.getSyncStatus();
            if (isSyncing || isOptimistic || elOffline) {
                // 206: Node is syncing but can serve incomplete data
                return { status: syncingStatus ?? routes.node.NodeHealth.SYNCING };
            }
            // 200: Node is ready
            return { status: routes.node.NodeHealth.READY };
            // else {
            //   503: Node not initialized or having issues
            //   NOTE: Lodestar does not start its API until fully initialized, so this status can never be served
            // }
        },
    };
}
/** Prefix commit with 0x as required by the beacon-APIs spec */
function toSpecClientVersion(cv) {
    return { ...cv, commit: `0x${cv.commit}` };
}
//# sourceMappingURL=index.js.map