/**
 * Worldline-first public handle for application read/write workflows.
 *
 * This surface intentionally wraps only the minimum commitment and revelation
 * functions needed by first-use application code. Substrate diagnostics remain
 * on WarpCore/openWarpGraph compatibility surfaces.
 */
import WarpError from "./errors/WarpError.js";
import QueryError from "./errors/QueryError.js";
import WarpWorldlineCoordinate from "./WarpWorldlineCoordinate.js";
import WarpWorldlineOpticBasis from "./WarpWorldlineOpticBasis.js";
import { openRuntimeHostProduct } from "./warp/RuntimeHostProduct.js";
import CheckpointTailBasisVerifier from "./services/optic/CheckpointTailBasisVerifier.js";
import createBoundedMemoryCapabilityReport from "./memory/createBoundedMemoryCapabilityReport.js";
export default class WarpWorldline {
    worldlineName;
    writerId;
    _commitPatch;
    _createWorldline;
    _prepareOpticBasis;
    _getFrontier;
    _readOpticBasis;
    _readCapabilities;
    constructor(options) {
        assertNonEmpty(options.worldlineName, 'worldlineName');
        assertNonEmpty(options.writerId, 'writerId');
        this.worldlineName = options.worldlineName;
        this.writerId = options.writerId;
        this._commitPatch = options.commitPatch;
        this._createWorldline = options.createWorldline;
        this._prepareOpticBasis = options.prepareOpticBasis ?? null;
        this._getFrontier = options.getFrontier ?? null;
        this._readOpticBasis = options.readOpticBasis ?? null;
        this._readCapabilities = options.readCapabilities ?? createBoundedMemoryCapabilityReport;
        Object.freeze(this);
    }
    async commit(build) {
        return await this._commitPatch(build);
    }
    live() {
        return this._createWorldline();
    }
    async seek(options) {
        return await this.live().seek(options);
    }
    async observer(nameOrConfig, config) {
        const worldline = this.live();
        if (typeof nameOrConfig === 'string') {
            if (config === undefined) {
                throw new WarpError('WarpWorldline observer requires an aperture config', 'E_WARP_WORLDLINE_OBSERVER_CONFIG');
            }
            return await worldline.observer(nameOrConfig, config);
        }
        return await worldline.observer(nameOrConfig);
    }
    optic() {
        return this.live().optic();
    }
    capabilities() {
        return this._readCapabilities();
    }
    async prepareOpticBasis() {
        if (this._prepareOpticBasis === null) {
            throw new WarpError('WarpWorldline was not opened with optic basis preparation support', 'E_WARP_WORLDLINE_OPTIC_BASIS_UNAVAILABLE');
        }
        return await this._prepareOpticBasis();
    }
    async coordinate() {
        if (this._getFrontier === null || this._readOpticBasis === null) {
            throw new WarpError('WarpWorldline was not opened with coordinate support', 'E_WARP_WORLDLINE_COORDINATE_UNAVAILABLE');
        }
        const basis = this._readOpticBasis();
        if (basis === null) {
            throw new QueryError('worldline coordinate requires a prepared checkpoint-tail optic basis', {
                code: 'E_OPTIC_NO_BOUNDED_BASIS',
                context: {
                    graphName: this.worldlineName,
                    reason: 'missing-prepared-worldline-coordinate-basis',
                },
            });
        }
        return new WarpWorldlineCoordinate({
            worldlineName: this.worldlineName,
            checkpointSha: basis.checkpointSha,
            frontier: await this._getFrontier(),
            createWorldline: this._createWorldline,
        });
    }
}
export async function openWarpWorldline(options) {
    assertNonEmpty(options.worldlineName, 'worldlineName');
    assertNonEmpty(options.writerId, 'writerId');
    const { worldlineName, ...graphOptions } = options;
    const graph = await openRuntimeHostProduct({
        ...graphOptions,
        graphName: worldlineName,
    });
    let preparedOpticBasis = null;
    return new WarpWorldline({
        worldlineName,
        writerId: graph.writerId,
        commitPatch: async (build) => await graph.patch(build),
        createWorldline: (worldlineOptions) => graph.worldline(worldlineOptions),
        prepareOpticBasis: async () => {
            const basis = await new CheckpointTailBasisVerifier({ source: graph }).verify();
            preparedOpticBasis = new WarpWorldlineOpticBasis({
                worldlineName,
                checkpointSha: basis.checkpointSha,
            });
            return preparedOpticBasis;
        },
        getFrontier: async () => await graph.getFrontier(),
        readOpticBasis: () => preparedOpticBasis,
    });
}
function assertNonEmpty(value, field) {
    if (typeof value !== 'string' || value.trim().length === 0) {
        throw new WarpError('WarpWorldline requires non-empty identity fields', 'E_WARP_WORLDLINE_IDENTITY', { context: { field } });
    }
}
