"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.createProfileLogic = createProfileLogic;
const CustomError_1 = require("../logic/CustomError");
const debug = __importStar(require("../util/debug"));
const ns_1 = require("../util/ns");
const utils_1 = require("../util/utils");
function createProfileLogic(store, authn, utilityLogic) {
    const ns = ns_1.ns;
    /**
     * loads the preference without throwing errors - if it can create it it does so.
     * remark: it still throws error if it cannot load profile.
     * @param user
     * @returns undefined if preferenceFile cannot be returned or NamedNode if it can find it or create it
     */
    async function silencedLoadPreferences(user) {
        try {
            return await loadPreferences(user);
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
        }
        catch (err) {
            return undefined;
        }
    }
    /**
     * loads the preference without returning different errors if it cannot create or load it.
     * remark: it also throws error if it cannot load profile.
     * @param user
     * @returns undefined if preferenceFile cannot be an Error or NamedNode if it can find it or create it
     */
    async function loadPreferences(user) {
        await loadProfile(user);
        const possiblePreferencesFile = (0, utils_1.suggestPreferencesFile)(user);
        let preferencesFile;
        try {
            preferencesFile = await utilityLogic.followOrCreateLink(user, ns.space('preferencesFile'), possiblePreferencesFile, user.doc());
        }
        catch (err) {
            const message = `User ${user} has no pointer in profile to preferences file.`;
            debug.warn(message);
            // we are listing the possible errors
            if (err instanceof CustomError_1.NotEditableError) {
                throw err;
            }
            if (err instanceof CustomError_1.WebOperationError) {
                throw err;
            }
            if (err instanceof CustomError_1.UnauthorizedError) {
                throw err;
            }
            if (err instanceof CustomError_1.CrossOriginForbiddenError) {
                throw err;
            }
            if (err instanceof CustomError_1.SameOriginForbiddenError) {
                throw err;
            }
            if (err instanceof CustomError_1.FetchError) {
                throw err;
            }
            throw err;
        }
        try {
            await store.fetcher.load(preferencesFile);
        }
        catch (err) { // Maybe a permission problem or origin problem
            const msg = `Unable to load preference of user ${user}: ${err}`;
            debug.warn(msg);
            if (err.response.status === 401) {
                throw new CustomError_1.UnauthorizedError();
            }
            if (err.response.status === 403) {
                if ((0, utils_1.differentOrigin)(preferencesFile)) {
                    throw new CustomError_1.CrossOriginForbiddenError();
                }
                throw new CustomError_1.SameOriginForbiddenError();
            }
            /*if (err.response.status === 404) {
                throw new NotFoundError();
            }*/
            throw new Error(msg);
        }
        return preferencesFile;
    }
    async function loadProfile(user) {
        if (!user) {
            throw new Error('loadProfile: no user given.');
        }
        try {
            await store.fetcher.load(user.doc());
        }
        catch (err) {
            throw new Error(`Unable to load profile of user ${user}: ${err}`);
        }
        return user.doc();
    }
    async function loadMe() {
        const me = authn.currentUser();
        if (me === null) {
            throw new Error('Current user not found! Not logged in?');
        }
        await store.fetcher.load(me.doc());
        return me;
    }
    function getPodRoot(user) {
        const podRoot = findStorage(user);
        if (!podRoot) {
            throw new Error('User pod root not found!');
        }
        return podRoot;
    }
    async function getMainInbox(user) {
        await store.fetcher.load(user);
        const mainInbox = store.any(user, ns.ldp('inbox'), undefined, user.doc());
        if (!mainInbox) {
            throw new Error('User main inbox not found!');
        }
        return mainInbox;
    }
    function findStorage(me) {
        return store.any(me, ns.space('storage'), undefined, me.doc());
    }
    return {
        loadMe,
        getPodRoot,
        getMainInbox,
        findStorage,
        loadPreferences,
        loadProfile,
        silencedLoadPreferences
    };
}
//# sourceMappingURL=profileLogic.js.map