import WarpCore from "./WarpCore.js";
import WarpError from "./errors/WarpError.js";
const APP_SURFACE_METHOD_NAMES = Object.freeze([
    'writer',
    'createPatch',
    'patch',
    'patchMany',
    'syncWith',
    'worldline',
    'observer',
    'translationCost',
    'subscribe',
    'watch',
]);
function hasFunction(value, name) {
    return typeof Reflect.get(value, name) === 'function';
}
function hasString(value, name) {
    return typeof Reflect.get(value, name) === 'string';
}
function isAppSurface(value) {
    return (hasString(value, 'graphName') &&
        hasString(value, 'writerId') &&
        APP_SURFACE_METHOD_NAMES.every((name) => hasFunction(value, name)));
}
function requireAppSurface(core, code) {
    if (isAppSurface(core)) {
        return core;
    }
    throw new WarpError('WarpApp requires a capability-backed WarpCore surface', code);
}
/**
 * Legacy curated WARP application surface.
 *
 * `WarpApp` remains supported for compatibility with existing application
 * builders and agentic CLI usage. New application code should open a named
 * worldline with openWarpWorldline() and keep substrate access out of the
 * first-use path.
 *
 * @deprecated For new application workflows, use openWarpWorldline(). WarpApp
 * remains supported as a compatibility facade while graph-first APIs migrate
 * to worldline/optic-first docs.
 */
export default class WarpApp {
    _core;
    constructor(core) {
        this._core = core;
    }
    static async open(options) {
        return new WarpApp(await WarpCore.open(options));
    }
    get graphName() {
        return this._surface().graphName;
    }
    get writerId() {
        return this._surface().writerId;
    }
    core() {
        return this._core;
    }
    _surface() {
        return requireAppSurface(this._core, 'E_WARP_APP_SURFACE');
    }
    async writer(writerId) {
        return await this._surface().writer(writerId);
    }
    async createPatch() {
        return await this._surface().createPatch();
    }
    async patch(build) {
        return await this._surface().patch(build);
    }
    async patchMany(...builds) {
        return await this._surface().patchMany(...builds);
    }
    async syncWith(remote, options) {
        return await this._surface().syncWith(unwrapSyncRemote(remote), options);
    }
    worldline(options) {
        return this._surface().worldline(options);
    }
    async observer(nameOrConfig, configOrOptions, maybeOptions) {
        if (typeof nameOrConfig === 'string') {
            return await this._surface().observer(nameOrConfig, configOrOptions, maybeOptions);
        }
        return await this._surface().observer(nameOrConfig, configOrOptions);
    }
    async translationCost(configA, configB) {
        return await this._surface().translationCost(configA, configB);
    }
    subscribe(options) {
        return this._surface().subscribe(options);
    }
    watch(pattern, options) {
        return this._surface().watch(pattern, options);
    }
    async getContent(nodeId) {
        return await this._surface().getContent(nodeId);
    }
    async getContentStream(nodeId) {
        return await this._surface().getContentStream(nodeId);
    }
    async getContentOid(nodeId) {
        return await this._surface().getContentOid(nodeId);
    }
    async getContentMeta(nodeId) {
        return await this._surface().getContentMeta(nodeId);
    }
    async getEdgeContent(from, to, label) {
        return await this._surface().getEdgeContent(from, to, label);
    }
    async getEdgeContentStream(from, to, label) {
        return await this._surface().getEdgeContentStream(from, to, label);
    }
    async getEdgeContentOid(from, to, label) {
        return await this._surface().getEdgeContentOid(from, to, label);
    }
    async getEdgeContentMeta(from, to, label) {
        return await this._surface().getEdgeContentMeta(from, to, label);
    }
    async createStrand(options) {
        return await this.core().createStrand(options);
    }
    async getStrand(strandId) {
        return await this.core().getStrand(strandId);
    }
    async listStrands() {
        return await this.core().listStrands();
    }
    async braidStrand(strandId, options) {
        return await this.core().braidStrand(strandId, options);
    }
    async dropStrand(strandId) {
        return await this.core().dropStrand(strandId);
    }
    async createStrandPatch(strandId) {
        return await this.core().createStrandPatch(strandId);
    }
    async patchStrand(strandId, build) {
        return await this.core().patchStrand(strandId, build);
    }
    async queueStrandIntent(strandId, build) {
        return await this.core().queueStrandIntent(strandId, build);
    }
    async listStrandIntents(strandId) {
        return await this.core().listStrandIntents(strandId);
    }
    async tickStrand(strandId) {
        return await this.core().tickStrand(strandId);
    }
}
function unwrapSyncRemote(remote) {
    if (typeof remote === 'string') {
        return remote;
    }
    if (remote instanceof WarpApp) {
        return remote._surface();
    }
    if (isAppSurface(remote)) {
        return remote;
    }
    throw new WarpError('WarpApp sync requires a capability-backed WarpCore peer', 'E_WARP_APP_SYNC_REMOTE');
}
