/*
 * Copyright (c) 2023-2025 Datalayer, Inc.
 * Distributed under the terms of the Modified BSD License.
 */
import * as notebooks from '../api/spacer/notebooks.js';
import { ItemDTO } from './ItemDTO.js';
import { ItemTypes } from '../client/constants.js';
import { validateJSON } from '../api/utils/validation.js';
/**
 * Notebook domain model that extends the base Item class.
 * Provides notebook-specific functionality for managing Jupyter notebooks.
 *
 * @example
 * ```typescript
 * const notebook = await client.createNotebook(formData);
 * const kernelSpec = await notebook.getKernelSpec();
 * ```
 */
export class NotebookDTO extends ItemDTO {
    /**
     * Create a Notebook instance.
     *
     * @param data - Notebook data from API
     * @param client - Client instance
     */
    constructor(data, client) {
        super(data, client);
    }
    // ========================================================================
    // Abstract Method Implementations
    // ========================================================================
    /** Document type identifier. */
    get type() {
        this._checkDeleted();
        return ItemTypes.NOTEBOOK;
    }
    /** The cached name of the notebook. */
    get name() {
        this._checkDeleted();
        return (this._data.name_t ||
            this._data.notebook_name_s ||
            this._data.name ||
            '');
    }
    /** The cached content. */
    get content() {
        this._checkDeleted();
        if (!this._data.content && this._data.model_s) {
            try {
                return JSON.parse(this._data.model_s);
            }
            catch {
                return this._data.model_s;
            }
        }
        return this._data.content;
    }
    /** Get the current name from API. */
    async getName() {
        this._checkDeleted();
        // For now, return cached value - implement API call if needed
        return this.name;
    }
    /** Get when the notebook was last updated from API. */
    async getUpdatedAt() {
        this._checkDeleted();
        const dateStr = this._data.updated_at || this._data.update_ts_dt;
        if (!dateStr) {
            throw new Error('No update timestamp available for notebook');
        }
        return new Date(dateStr);
    }
    /** Update the notebook. */
    async update(name, description) {
        // FIXME: check if both are needed, and use the existing values if only one provided
        this._checkDeleted();
        const token = this._client.getToken();
        const spacerRunUrl = this._client.getSpacerRunUrl();
        const updateData = {};
        if (name !== undefined)
            updateData.name = name;
        if (description !== undefined)
            updateData.description = description;
        await notebooks.updateNotebook(token, this.uid, updateData, spacerRunUrl);
        // FIXME: handle partial updates
        return this;
    }
    // ========================================================================
    // Notebook-specific Properties
    // ========================================================================
    /** File path within the space. */
    get path() {
        this._checkDeleted();
        return this._data.path || '';
    }
    /** Version number. */
    get version() {
        this._checkDeleted();
        return this._data.version || 0;
    }
    /** Notebook metadata. */
    get metadata() {
        this._checkDeleted();
        return this._data.metadata || {};
    }
    /** Kernel specification (cached). */
    get kernelSpec() {
        this._checkDeleted();
        return this._data.kernel_spec;
    }
    /** Description of the notebook. */
    get description() {
        this._checkDeleted();
        return this._data.description_t || '';
    }
    /** Get the notebook extension. */
    get extension() {
        this._checkDeleted();
        const ext = this._data.notebook_extension_s;
        return ext ? (ext.startsWith('.') ? ext : `.${ext}`) : '.ipynb';
    }
    /**
     * Get notebook data in camelCase format.
     * Returns only the core fields that consumers need.
     * This provides a stable interface regardless of API changes.
     *
     * @returns Core notebook data with camelCase properties
     */
    toJSON() {
        this._checkDeleted();
        const obj = {
            id: this.id,
            uid: this.uid,
            name: this.name,
            description: this.description,
            type: this.type,
            extension: this.extension,
            cdnUrl: this._data.cdn_url_s,
        };
        validateJSON(obj, 'Notebook');
        return obj;
    }
    /**
     * Get the raw notebook data exactly as received from the API.
     * This preserves the original snake_case naming from the API response.
     *
     * @returns Raw notebook data from API
     */
    rawData() {
        this._checkDeleted();
        return this._data;
    }
}
