/*
 * Copyright (c) 2023-2025 Datalayer, Inc.
 * Distributed under the terms of the Modified BSD License.
 */
import { snapshots } from '../api/runtimes/index.js';
import { validateJSON } from '../api/utils/validation.js';
/**
 * Snapshot domain model that wraps API responses with convenient methods.
 * Provides runtime snapshot management with data refresh and lifecycle operations.
 *
 * @example
 * ```typescript
 * const snapshot = await runtime.createSnapshot('my-checkpoint');
 * const runtime = await snapshot.restore();
 * ```
 */
export class RuntimeSnapshotDTO {
    _data;
    _client;
    _deleted = false;
    /**
     * Create a Runtime Snapshot instance.
     *
     * @param data - Snapshot data from API
     * @param client - Client instance
     */
    constructor(data, client) {
        this._data = data;
        this._client = client;
    }
    // ========================================================================
    // Helper Methods
    // ========================================================================
    /**
     * Check if this snapshot has been deleted and throw error if so.
     * @throws Error if deleted
     */
    _checkDeleted() {
        if (this._deleted) {
            throw new Error(`Snapshot ${this._data.uid} has been deleted and no longer exists`);
        }
    }
    // ========================================================================
    // Static Properties (set at creation, never change)
    // ========================================================================
    /** Unique identifier for the snapshot. */
    get uid() {
        this._checkDeleted();
        return this._data.uid;
    }
    /** Name of the snapshot. */
    get name() {
        this._checkDeleted();
        return this._data.name;
    }
    /** Description of the snapshot. */
    get description() {
        this._checkDeleted();
        return this._data.description || '';
    }
    /** Name of the environment used by the runtime. */
    get environment() {
        this._checkDeleted();
        return this._data.environment;
    }
    /** When the snapshot was last updated. */
    get updatedAt() {
        this._checkDeleted();
        return new Date(this._data.updated_at);
    }
    // ========================================================================
    // Action Methods
    // ========================================================================
    /**
     * Delete this snapshot permanently.
     * After deletion, subsequent calls to dynamic methods will throw errors.
     */
    async delete() {
        this._checkDeleted();
        const token = this._client.getToken();
        const runtimesRunUrl = this._client.getRuntimesRunUrl();
        await snapshots.deleteSnapshot(token, this.uid, runtimesRunUrl);
        this._deleted = true;
    }
    /**
     * Create a runtime from this snapshot (restore functionality).
     *
     * @param minutesLimit - Time limit in minutes for the restored runtime
     * @returns Created Runtime instance
     */
    async restore(minutesLimit) {
        this._checkDeleted();
        return await this._client.createRuntime({
            environmentName: this.environment,
            type: 'notebook',
            givenName: `Restored from ${this.name}`,
            minutesLimit: minutesLimit,
            fromSnapshotId: this.uid,
        });
    }
    // ========================================================================
    // Utility Methods
    // ========================================================================
    /**
     * Get snapshot data in camelCase format.
     * Returns only the core fields that consumers need.
     * This provides a stable interface regardless of API changes.
     * Note: Returns current cached state - call getStatus() first if you need fresh data.
     *
     * @returns Core snapshot data with camelCase properties
     */
    toJSON() {
        this._checkDeleted();
        const obj = {
            uid: this.uid,
            name: this.name,
            description: this.description,
            environment: this.environment,
            updatedAt: this.updatedAt.toISOString(),
        };
        validateJSON(obj, 'Snapshot');
        return obj;
    }
    /**
     * Get the raw snapshot data exactly as received from the API.
     * This preserves the original snake_case naming from the API response.
     *
     * @returns Raw snapshot data from API
     */
    rawData() {
        this._checkDeleted();
        return this._data;
    }
    /** String representation of the snapshot. */
    toString() {
        this._checkDeleted();
        return `Snapshot(${this.uid}, ${this.name})`;
    }
}
