"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const FileBase_1 = require("../storage/FileBase");
const Utilities_1 = require("../core/Utilities");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const GitHubStorage_1 = require("./GitHubStorage");
const CartoApp_1 = require("../app/CartoApp");
const axios_1 = require("axios");
const Log_1 = require("../core/Log");
// import { Endpoints } from '@octokit/types';
// type getContentReposResponse = Endpoints["GET /repos/{owner}/{repo}/contents/{path}"]["response"];
class GitHubFile extends FileBase_1.default {
    _name;
    _parentFolder;
    sha;
    get name() {
        return this._name;
    }
    get isContentLoaded() {
        return this.lastLoadedOrSaved !== null;
    }
    get parentFolder() {
        return this._parentFolder;
    }
    get fullPath() {
        let path = this._parentFolder.fullPath;
        if (!path.endsWith(GitHubStorage_1.default.slashFolderDelimiter)) {
            path += GitHubStorage_1.default.slashFolderDelimiter;
        }
        path += this._name;
        return path;
    }
    constructor(parentFolder, folderName) {
        super();
        this._parentFolder = parentFolder;
        this._name = folderName;
    }
    async deleteThisFile(skipRemoveFromParent) {
        throw new Error("Not implemented.");
    }
    async moveTo(newStorageRelativePath) {
        throw new Error("Not implemented.");
    }
    async loadContent(force) {
        if (force || !this.lastLoadedOrSaved) {
            this._content = null;
            const storage = this._parentFolder.storage;
            // on web sources, use GH APIs to retrieve content because that should work from a web/CORS/permissions perspective to retrieve binary files
            // on non-web sources, just retrieve the binary directly from raw.githubusercontent.com
            if (CartoApp_1.default.isWeb) {
                const octo = storage.manager.octokit;
                let fullPathMinusSlash = this.fullPath;
                if (fullPathMinusSlash.startsWith("/")) {
                    fullPathMinusSlash = fullPathMinusSlash.substring(1, fullPathMinusSlash.length);
                }
                let file = undefined;
                try {
                    file = await octo.rest.repos.getContent({
                        owner: storage.ownerName,
                        repo: storage.repoName,
                        ref: storage.branch,
                        path: fullPathMinusSlash,
                    });
                }
                catch (e) {
                    if (e.name && e.name === "HttpError" && e.message.indexOf("rate limit") >= 0) {
                        throw new Error(e.message);
                    }
                    else {
                        Log_1.default.debugAlert("Could not get content for GitHub file: '" + e.toString() + "'");
                    }
                }
                if (file) {
                    const fileData = file.data;
                    if (fileData.content !== undefined && fileData.encoding !== undefined) {
                        if (fileData.encoding === "base64") {
                            let contentA = fileData.content;
                            if (contentA && typeof contentA === "string") {
                                contentA = contentA.replace(/\n/gi, "");
                            }
                            this._content = new Uint8Array(Utilities_1.default.base64ToArrayBuffer(contentA));
                            const preferredEncoding = StorageUtilities_1.default.getEncodingByFileName(this.name);
                            if (preferredEncoding === StorageUtilities_1.EncodingType.Utf8String) {
                                const result = Utilities_1.default.readStringUTF8(new DataView(this._content.buffer), 0, this._content.length);
                                this._content = result.str;
                            }
                        }
                        else {
                            this._content = fileData.content;
                        }
                    }
                }
            }
            else {
                this._content = null;
                /*      if (this.fullPath.startsWith("/")) {
                path = this.fullPath.substring(1, this.fullPath.length);
              }*/
                const ghs = this._parentFolder.storage;
                const path = "https://raw.githubusercontent.com/" +
                    ghs.ownerName +
                    "/" +
                    ghs.repoName +
                    "/" +
                    (ghs.branch ? ghs.branch : "main") +
                    Utilities_1.default.ensureStartsWithSlash(this.fullPath);
                if (StorageUtilities_1.default.getEncodingByFileName(this.name) === StorageUtilities_1.EncodingType.ByteBuffer) {
                    let response = undefined;
                    try {
                        response = await axios_1.default.get(path, {
                            responseType: "arraybuffer",
                            headers: {},
                        });
                    }
                    catch (e) {
                        Log_1.default.error("Could not retrieve file '" + this.fullPath + "' from '" + path + "' - " + e.toString());
                        this.lastLoadedOrSaved = new Date();
                        return this.lastLoadedOrSaved;
                    }
                    this._content = new Uint8Array(response.data);
                }
                else {
                    let response = undefined;
                    try {
                        response = await axios_1.default.get(path, {
                            headers: {},
                        });
                    }
                    catch (e) {
                        Log_1.default.error("Could not retrieve file '" + this.fullPath + "' - " + e.toString(), path);
                        this.lastLoadedOrSaved = new Date();
                        return this.lastLoadedOrSaved;
                    }
                    let result = response.data;
                    if (typeof result === "object") {
                        try {
                            result = JSON.stringify(result, null, 2);
                        }
                        catch (e) {
                            Log_1.default.fail("Could not convert file to JSON");
                        }
                    }
                    if (response.status !== 200) {
                        Log_1.default.fail("Could not retrieve file from '" + path + "' - response code is " + response.status);
                        Log_1.default.verbose("Could not retrieve file from '" + path + "' - response code is " + response.status);
                    }
                    if (result === null || result === "null") {
                        Log_1.default.fail("Could not retrieve file from '" + path + "' - result is null.");
                        Log_1.default.verbose("Could not retrieve file from '" + path + "' - result is null.");
                    }
                    this._content = result;
                }
            }
            this.lastLoadedOrSaved = new Date();
        }
        return this.lastLoadedOrSaved;
    }
    setContent(newContent) {
        const areEqual = StorageUtilities_1.default.contentsAreEqual(this._content, newContent);
        if (!areEqual) {
            this._content = newContent;
            this.contentWasModified();
        }
    }
    async saveContent() {
        if (this.parentFolder.storage.readOnly) {
            throw new Error("Can't save read-only file.");
        }
        this.lastLoadedOrSaved = new Date();
        return this.lastLoadedOrSaved;
    }
}
exports.default = GitHubFile;

//# sourceMappingURL=../maps/github/GitHubFile.js.map
