import LocalStorage from "../LocalStorage";
import Navigation from "../Navigation";
import PermissionUtil from "../Permission";
import User from "../User";
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
import HTTPMethod from "../../../Types/API/HTTPMethod";
import HTTPResponse from "../../../Types/API/HTTPResponse";
import Route from "../../../Types/API/Route";
import URL from "../../../Types/API/URL";
import JSONFunctions from "../../../Types/JSONFunctions";
import API from "../../../Utils/API";
import { IDENTITY_URL } from "../../Config";
class BaseAPI extends API {
    constructor(protocol, hostname, route) {
        super(protocol, hostname, route);
    }
    static fromURL(url) {
        return new BaseAPI(url.protocol, url.hostname, url.route);
    }
    static async onResponseSuccessHeaders(headers) {
        if (headers && headers["global-permissions"]) {
            PermissionUtil.setGlobalPermissions(JSONFunctions.deserialize(JSONFunctions.parseJSONObject(headers["global-permissions"])));
        }
        if (headers && headers["global-permissions-hash"]) {
            LocalStorage.setItem("global-permissions-hash", headers["global-permissions-hash"]);
        }
        if (headers && headers["project-permissions"]) {
            PermissionUtil.setProjectPermissions(JSONFunctions.deserialize(JSONFunctions.parseJSONObject(headers["project-permissions"])));
        }
        if (headers && headers["project-permissions-hash"]) {
            LocalStorage.setItem("project-permissions-hash", headers["project-permissions-hash"]);
        }
        return Promise.resolve(headers);
    }
    static getHeaders() {
        let defaultHeaders = this.getDefaultHeaders();
        const headers = {};
        const globalPermissionsHash = LocalStorage.getItem("global-permissions-hash");
        if (globalPermissionsHash) {
            headers["global-permissions-hash"] = globalPermissionsHash;
        }
        const projectPermissionsHash = LocalStorage.getItem("project-permissions-hash");
        if (projectPermissionsHash) {
            headers["project-permissions-hash"] = projectPermissionsHash;
        }
        defaultHeaders = Object.assign(Object.assign({}, defaultHeaders), headers);
        return defaultHeaders;
    }
    static logoutUser() {
        return User.logout();
    }
    static handleError(error) {
        /*
         * 405 Status - Tenant not found. If Project was deleted.
         * 401 Status - User is not logged in.
         * 403 Status - Forbidden. If the IP address is not whitelisted (for example).
         */
        if (error instanceof HTTPErrorResponse &&
            (error.statusCode === 401 || error.statusCode === 405)) {
            const loginRoute = this.getLoginRoute();
            this.logoutUser();
            if (Navigation.getQueryStringByName("token")) {
                Navigation.navigate(loginRoute.addRouteParam("sso", "true"), {
                    forceNavigate: true,
                });
            }
            else {
                Navigation.navigate(loginRoute, {
                    forceNavigate: true,
                });
            }
        }
        if (error instanceof HTTPErrorResponse &&
            error.statusCode === 403 &&
            Navigation.getCurrentRoute().toString() !==
                this.getForbiddenRoute().toString()) {
            Navigation.navigate(this.getForbiddenRoute(), { forceNavigate: true });
        }
        return error;
    }
    static async tryRefreshAuth(_context) {
        if (!this.refreshPromise) {
            this.refreshPromise = (async () => {
                const refreshUrl = URL.fromString(IDENTITY_URL.toString()).addRoute("/refresh-token");
                const result = await super.fetch({
                    method: HTTPMethod.POST,
                    url: refreshUrl,
                    options: {
                        skipAuthRefresh: true,
                        hasAttemptedAuthRefresh: true,
                    },
                });
                if (result instanceof HTTPResponse && result.isSuccess()) {
                    return true;
                }
                return false;
            })().finally(() => {
                this.refreshPromise = null;
            });
        }
        return await this.refreshPromise;
    }
    static getLoginRoute() {
        return new Route("/accounts/login");
    }
    static getForbiddenRoute() {
        return new Route("/accounts/forbidden");
    }
    static getFriendlyMessage(err) {
        if (err instanceof HTTPErrorResponse) {
            if (err.statusCode === 502 || err.statusCode === 504) {
                return "Error connecting to server. Please try again in few minutes.";
            }
            return err.message || "Server Error. Please try again";
        }
        if (err instanceof Error) {
            return err.message || "Server Error. Please try again";
        }
        if (typeof err === "string") {
            return err || "Server Error. Please try again";
        }
        /*
         * Never surface a raw object as "[object Object]" — pull a message
         * out of it (gateways/proxies often send `{ message }` or `{ error }`)
         * or stringify it so the UI shows something actionable.
         */
        if (err && typeof err === "object") {
            const obj = err;
            if (typeof obj.message === "string" && obj.message) {
                return obj.message;
            }
            if (typeof obj.error === "string" && obj.error) {
                return obj.error;
            }
            try {
                return JSON.stringify(err);
            }
            catch (_a) {
                return "Server Error. Please try again";
            }
        }
        return "Server Error. Please try again";
    }
}
BaseAPI.refreshPromise = null;
export default BaseAPI;
//# sourceMappingURL=API.js.map