"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const NodeStorage_1 = require("./NodeStorage");
const FileBase_1 = require("../storage/FileBase");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const crypto = require("crypto");
const fs = require("fs");
class NodeFile extends FileBase_1.default {
    _name;
    _parentFolder;
    get name() {
        return this._name;
    }
    get fullPath() {
        let path = this._parentFolder.fullPath;
        if (!path.endsWith(NodeStorage_1.default.platformFolderDelimiter)) {
            path += NodeStorage_1.default.platformFolderDelimiter;
        }
        return path + this.name;
    }
    get parentFolder() {
        return this._parentFolder;
    }
    get isContentLoaded() {
        return this.lastLoadedOrSaved != null || this.modified != null;
    }
    constructor(parentFolder, folderName) {
        super();
        this._parentFolder = parentFolder;
        this._name = folderName;
    }
    async exists() {
        return fs.existsSync(this.fullPath);
    }
    async loadContent(force) {
        if (force || this.lastLoadedOrSaved == null) {
            const encoding = StorageUtilities_1.default.getEncodingByFileName(this._name);
            if (!fs.existsSync(this.fullPath)) {
                this._content = null;
            }
            else if (encoding === StorageUtilities_1.EncodingType.ByteBuffer) {
                // Log.debug(`NodeFS loading '${this.fullPath}' as binary.`);
                const byteResult = fs.readFileSync(this.fullPath);
                if (byteResult instanceof ArrayBuffer) {
                    this._content = new Uint8Array(byteResult);
                }
                else {
                    this._content = byteResult;
                }
            }
            else {
                // Log.debug(`NodeFS loading '${this.fullPath}' as text.`);
                this._content = fs.readFileSync(this.fullPath, { encoding: "utf8" });
            }
            //  this._content += "";
            this.lastLoadedOrSaved = new Date();
        }
        return this.lastLoadedOrSaved;
    }
    setContent(newContent) {
        const areEqual = StorageUtilities_1.default.contentsAreEqual(this._content, newContent);
        if (!areEqual) {
            if (!this.lastLoadedOrSaved) {
                this.lastLoadedOrSaved = new Date();
                this.lastLoadedOrSaved = new Date(this.lastLoadedOrSaved.getTime() - 1);
                // Log.debugAlert("Setting a file without loading it first.");
            }
            this._content = newContent;
            this.contentWasModified();
        }
    }
    async getHash() {
        await this.loadContent(false);
        if (this._content === undefined || this._content === null) {
            return undefined;
        }
        const hash = crypto.createHash("MD5");
        hash.update(this._content);
        return hash.digest("base64");
    }
    async saveContent() {
        if (this.parentFolder.storage.readOnly) {
            throw new Error("Can't save read-only file.");
        }
        if (this.needsSave) {
            this.lastLoadedOrSaved = new Date();
            if (this.content != null) {
                this.parentFolder.ensureExists();
                const encoding = StorageUtilities_1.default.getEncodingByFileName(this._name);
                if (encoding === StorageUtilities_1.EncodingType.ByteBuffer) {
                    // Log.verbose("Saving '" + this.fullPath + "' as binary. size: " + this.content.length);
                    fs.writeFileSync(this.fullPath, this.content);
                }
                else {
                    // Log.verbose("Saving '" + this.fullPath + "' as text. size: " + this.content.length);
                    fs.writeFileSync(this.fullPath, this.content, { encoding: "utf8" });
                }
            }
        }
        if (this.lastLoadedOrSaved === null) {
            this.lastLoadedOrSaved = new Date();
        }
        return this.lastLoadedOrSaved;
    }
    async writeContent(content) {
        this.lastLoadedOrSaved = new Date();
        let writer = fs.createWriteStream(this.fullPath);
        for (const str of content) {
            writer.write(str + "\r\n");
        }
        writer.end();
    }
    async deleteThisFile(skipRemoveFromParent) {
        if (this.parentFolder.storage.readOnly) {
            throw new Error("Can't save read-only file.");
        }
        if (skipRemoveFromParent !== true) {
            this._parentFolder._removeFile(this);
        }
        return this._deleteItem(this.fullPath);
    }
    async moveTo(newStorageRelativePath) {
        const newFolderPath = StorageUtilities_1.default.getFolderPath(newStorageRelativePath);
        const newFileName = StorageUtilities_1.default.getLeafName(newStorageRelativePath);
        if (newFileName.length < 2) {
            throw new Error("New path is not correct.");
        }
        const newParentFolder = await this._parentFolder.storage.ensureFolderFromStorageRelativePath(newFolderPath);
        if (newParentFolder.files[newFileName] !== undefined) {
            throw new Error("File exists at specified path.");
        }
        await this.loadContent(false);
        const originalPath = this.fullPath;
        this._name = newFileName;
        this._parentFolder = newParentFolder;
        this.modified = new Date();
        newParentFolder._addExistingFile(this);
        this._deleteItem(originalPath);
        return true;
    }
    async _deleteItem(path) {
        let isSuccess = true;
        try {
            fs.rmSync(path);
        }
        catch (e) {
            isSuccess = false;
        }
        return isSuccess;
    }
}
exports.default = NodeFile;

//# sourceMappingURL=../maps/local/NodeFile.js.map
