/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter UniSharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../../unisharp/Utils");
const Stream = require("./../../../unisharp/Stream");
const MemoryStream = require("./../../../unisharp/MemoryStream");

const BaseArchiveStorage = require("./BaseArchiveStorage");
const StreamUtils = require("./StreamUtils");
const FileUpdateMode = require("./FileUpdateMode");

/**
 * An <see cref="IArchiveStorage"/> implementation suitable for in memory streams.
 */
class MemoryArchiveStorage extends BaseArchiveStorage {
    
    /**
     * Initializes a new instance of the <see cref="MemoryArchiveStorage"/> class.
     * @param _updateMode The <see cref="FileUpdateMode"/> to use
     */
    constructor(_updateMode = FileUpdateMode.DIRECT) {
        super(_updateMode);
        this.temporaryStream_ = null;
        this.finalStream_ = null;
    }
    
    get finalStream() {
        return this.finalStream_;
    }
    
    /**
     * Gets the temporary output <see cref="Stream"/>
     * @return Returns the temporary output stream.
     */
    getTemporaryOutput() {
        this.temporaryStream_ = new MemoryStream();
        return this.temporaryStream_;
    }
    
    /**
     * Converts the temporary <see cref="Stream"/> to its final form.
     * @return Returns a <see cref="Stream"/> that can be used to read 
     * the final storage for the archive.
     */
    convertTemporaryToFinal() {
        if (this.temporaryStream_ === null) 
            throw new Error("No temporary stream has been created");
        this.finalStream_ = new MemoryStream(this.temporaryStream_.toByteArray());
        return this.finalStream_;
    }
    
    /**
     * Make a temporary copy of the original stream.
     * @param stream The <see cref="Stream"/> to copy.
     * @return Returns a temporary output <see cref="Stream"/> that is a copy of the input.
     */
    makeTemporaryCopy(stream) {
        this.temporaryStream_ = new MemoryStream();
        stream.position = 0;
        StreamUtils.copy(stream, this.temporaryStream_, new Uint8Array(4096));
        return this.temporaryStream_;
    }
    
    /**
     * Return a stream suitable for performing direct updates on the original source.
     * @param stream The original source stream
     * @return Returns a stream suitable for direct updating.
     */
    openForDirectUpdate(stream) {
        if ((stream === null) || !stream.canWrite()) {
            let result = new MemoryStream();
            if (stream !== null) {
                stream.position = 0;
                StreamUtils.copy(stream, result, new Uint8Array(4096));
                stream.close();
            }
            return result;
        }
        else 
            return stream;
    }
    
    /**
     * Disposes this instance.
     */
    close() {
        if (this.temporaryStream_ !== null) {
            this.temporaryStream_.close();
            this.temporaryStream_ = null;
        }
    }
}


module.exports = MemoryArchiveStorage