/* COPYRIGHT Esri - https://js.arcgis.com/1.2/LICENSE.txt */
import * as n from "@esri/solution-common";
import a from "@arcgis/core/identity/IdentityManager.js";
import h from "@arcgis/core/identity/OAuthInfo.js";
import c from "@arcgis/core/portal/Portal.js";
class g {
  constructor(e, t, r, s) {
    this._credential = void 0, this._isEnterprise = !1, this._locale = "en", this._portalSubset = void 0, this._portalUserSubset = void 0, this._searchArcGISOnlineEnabled = !0, this._signInParam = void 0, this._clientId = e ?? "", this._locale = r ?? "en", this._portalUrl = t ?? "https://www.arcgis.com", this._portalRestUrl = this._portalUrl + "/sharing/rest", this._portalUrl = location.origin.endsWith(".arcgis.com") ? window.location.origin : this._portalUrl, this._signInParam = s;
    const i = new h({
      appId: this._clientId,
      locale: this._locale,
      popup: !1,
      // inline redirects don't require any additional app configuration
      portalUrl: this._portalUrl,
      preserveUrlHash: !0
    });
    try {
      a.registerOAuthInfos([i]);
    } catch (o) {
      console.log(o);
    }
    this._portal = new c({ url: this._portalUrl });
  }
  get Credential() {
    return this._credential;
  }
  get IsEnterprisePortal() {
    return this._isEnterprise;
  }
  get IsSignedIn() {
    return !!this._credential;
  }
  get Portal() {
    return this._portal;
  }
  get PortalSubset() {
    return this._portalSubset;
  }
  get PortalUrl() {
    return this._portalUrl;
  }
  get PortalUserOrg() {
    return this._portalSubset && this._portalSubset.id;
  }
  get PortalUserName() {
    return this._portalUserSubset && this._portalUserSubset.username || "";
  }
  get PortalUserSubset() {
    return this._portalUserSubset;
  }
  get PortalUserPrivileges() {
    let e = [];
    return this._portalUserSubset?.privileges && (e = this._portalUserSubset.privileges), e;
  }
  get SignInParam() {
    return this._signInParam;
  }
  get CanDeleteSolution() {
    return this.PortalUserPrivileges.includes("portal:admin:deleteItems");
  }
  get CanUpdateSolution() {
    return this.PortalUserPrivileges.includes("portal:admin:updateItems");
  }
  get CanUseAI() {
    const e = this._portalSubset?.orgSettings, t = this.PortalUserPrivileges.includes("portal:user:useAIAssistants");
    return e?.aiAssistantsEnabled ? e.aiAssistantsEnabled && !e.blockBetaApps && t : !1;
  }
  get CanViewOrg() {
    return this.PortalUserPrivileges.includes("portal:admin:viewItems");
  }
  get CanSearchArcGISOnline() {
    return this._searchArcGISOnlineEnabled;
  }
  get RestUserSession() {
    const e = a.findServerInfo(this._portalRestUrl), t = this._credential ? n.UserSession.fromCredential(this._credential, e) : this._isEnterprise ? new n.UserSession({}) : new n.UserSession({ portal: this._portalRestUrl });
    return t.portal = this.PortalSubset?.restUrl ? this.PortalSubset?.restUrl : t.portal, t.clientId = this._credential?._oAuthCred?.appId, t._refreshToken = this._credential?._oAuthCred?.refreshToken, t;
  }
  /**
   * Initializes the Auth object. This method must be called before any other Auth methods.
   * If the user is not authorized to use the app, the page will be redirected to an error page.
   *
   * @returns Promise that resolves with the initialized Auth object
   */
  async initialize() {
    try {
      await this._init();
    } catch {
      this.destroy();
    }
    return this;
  }
  destroy() {
    this._credential = void 0, this._portalSubset = void 0, this._portalUserSubset = void 0, a.destroyCredentials();
  }
  /**
   * Signs into app and refreshes the window.location or switches to the supplied URL.
   *
   * @param signInParamValue If supplied, the parameter `signInParam` with the supplied value
   * will be added to the redirect uri's search params
   */
  async signIn(e = "") {
    a.setOAuthRedirectionHandler((t) => {
      const r = t.authorizeParams.redirect_uri;
      if (e.length > 0) {
        const s = r.split("?"), i = s[0];
        let o = "";
        const l = new URLSearchParams(s[1] || "");
        l.append("signInParam", e), o = "?" + l.toString(), t.authorizeParams.redirect_uri = i + o;
      }
      window.location.href = t.authorizeUrl + "?" + this._objectToQuery(t.authorizeParams);
    }), await a.getCredential((this._portalSubset?.portalUrl ?? this._portalUrl) + "/sharing").then(
      (t) => {
        t && window.location.reload();
      }
    );
  }
  /**
   * Signs out of app.
   * When the user is...
   *  on the solutions page they should stay on that page
   *  on a solutions details page they should stay on that page
   *  on the deployments page they should stay on that page
   *  on a deployed solutions page they should be sent to the deployments page
   *  on the resources page they should stay on that page
   */
  signOut() {
    const e = window.location.href, t = /[\/]\b([0-9A-Fa-f]){32}\b/g;
    let r = e.match(t) ? e.replace(t, "") : e;
    const i = `${this._portal?.restUrl ?? this._portalUrl + "/sharing/rest"}/oauth2/signout?client_id=${this._clientId}&redirect_uri=${encodeURIComponent(r)}`;
    this.destroy(), window.location.replace(i);
  }
  /**
   * Refreshes the user session token
   */
  refreshSession() {
    const e = this.RestUserSession;
    if (!(!e || !this.IsSignedIn))
      return e.exchangeRefreshToken();
  }
  // ---------------------------------------------------------------------------------------------------------------- //
  /**
   * Generates the organization URL.
   * @param portalUrl The URL to the portal instance.
   * @param portalUrlKey The prefix selected by the organization's administrator to be used with the customBaseURL.
   * @param portalCustomBaseUrl The custom base URL for the portal.
   * @returns
   */
  _getOrgUrl(e, t, r) {
    return t && r ? window.location.protocol + "//" + t.toLowerCase() + "." + r : e;
  }
  /**
   * Initializes the Auth object. This method must be called before any other Auth methods.
   * If the user is not authorized to use the app, the page will be redirected to an error page.
   * @returns Promise that resolves with the initialized Auth object
   */
  async _init() {
    try {
      this._credential = await a.checkSignInStatus(this._portalUrl + "/sharing");
    } catch {
    }
    try {
      const t = await a.checkAppAccess(this._portalUrl + "/sharing", this._clientId);
      (typeof t.valid < "u" && !t.valid || t.viewOnlyUserTypeApp) && window.location.replace(`error.html?error=blocked&locale=${this._locale}`), this._credential = t.credential;
    } catch (t) {
      t.name;
    }
    this._portal.authMode = "auto", await this._portal.load();
    const e = this._credential ? await n.getOrganizationSettings(this.RestUserSession) : {};
    if (this._isEnterprise = this._portal.isPortal, this._isEnterprise)
      try {
        const t = `${this._portal.restUrl}/portals/self/settings`, r = await n.request(t, {
          authentication: this._credential ? this.RestUserSession : void 0
        });
        r?.portalConfigProperties?.searchArcGISOnlineEnabled !== void 0 ? this._searchArcGISOnlineEnabled = r.portalConfigProperties.searchArcGISOnlineEnabled : this._searchArcGISOnlineEnabled = !1;
      } catch (t) {
        console.warn("Failed to fetch portal settings:", t), this._searchArcGISOnlineEnabled = !1;
      }
    else
      this._searchArcGISOnlineEnabled = !0;
    return this._portalSubset = {
      name: this._portal.name ?? "",
      id: this._portal.id ?? "",
      restUrl: this._portal.restUrl ?? "",
      portalUrl: this._portal.url ?? "",
      urlKey: this._portal.urlKey ?? "",
      hostName: this._portal.portalHostname ?? "",
      orgUrl: this._getOrgUrl(this._portal.url, this._portal.urlKey ?? "", this._portal.customBaseUrl ?? ""),
      locationTrackingEnabled: this._portal.helperServices.hasOwnProperty("locationTracking"),
      hubPremiumEnabled: this._portal.portalProperties?.hub?.enabled || !1,
      workflowURL: this._portal.helperServices?.workflowManager?.url ?? this._portal.url,
      isReadOnly: this._portal.isReadOnly,
      orgSettings: e
    }, this._portalUserSubset = {
      fullName: this._portal.user?.fullName ?? "",
      username: this._portal.user?.username ?? "",
      culture: this._portal.user?.culture?.toLowerCase() || "en",
      thumbnailUrl: this._portal.user?.thumbnailUrl || this._portal.url + "/home/js/arcgisonline/css/images/no-user-thumb.jpg",
      orgId: this._portal.user?.orgId ?? "",
      privileges: this._portal.user.privileges,
      role: this._portal.user?.role ?? "",
      roleId: this._portal.user?.roleId ?? void 0
    }, this._isEnterprise && this._portalSubset && (this._portalSubset.workflowURL = await n.getWorkflowEnterpriseServerRootURL(
      this._portal.restUrl,
      this.RestUserSession || new n.UserSession({})
    )), this._portal?.user?.roleId && this._portalUserSubset && (this._portalUserSubset.roleId = this._portal.user.roleId), this;
  }
  /**
   * Checks if an object is serializable.
   * @param obj Object to check
   * This function checks if the object has a `toJSON` method, which is a
   * @returns Boolean indicating whether the object is serializable.
   */
  _isSerializable(e) {
    return e && typeof e == "object" && "toJSON" in e && typeof e.toJSON == "function";
  }
  /**
   * Converts a hashmap of query parameters to a query string. Following formatting rules applies:
   *   - object values that implements `toJSON()` are stringified
   *   - array value will map to multiple key value pairs. ie `{ key: ["v1", "v2"] }` returns `key=v1&key=v2
   *
   * @param queryParameters the query parameters to convert to a string
   * @param replacers optional replacer functions defined per key
   *
   * @example
   * const queryParameters = {
   *   objectIds: [1, 2, 3, 4]
   * };
   *
   * // returns: "objectIds=1&objectIds=2&objectIds=3&objectIds=4"
   * objectToQuery(queryParameters);
   *
   * // returns: "objectIds=1,2,3,4"
   * objectToQuery(queryParameters, {
   *   objectIds: (v) => v.join(",")
   * });
   *
   * // returns: "objectIds=1,2,3,4"
   * objectToQuery(queryParameters, (k, v) => {
   *   switch (k) {
   *     case "objectIds":
   *       return v.join(","));
   *     default:
   *       return "" + v;
   *   }
   * });
   *
   * Copied from function exported in arcgis-js-api but not added to JSAPI.
   */
  _objectToQuery(e, t) {
    return e ? t && typeof t == "function" ? Object.keys(e).map((r) => encodeURIComponent(r) + "=" + encodeURIComponent(t(r, e[r]))).join("&") : Object.keys(e).map((r) => {
      const s = e[r];
      if (s == null)
        return "";
      const i = encodeURIComponent(r) + "=", o = t && t[r];
      return o ? i + encodeURIComponent(o(s)) : Array.isArray(s) ? s.map((l) => this._isSerializable(l) ? i + encodeURIComponent(JSON.stringify(l)) : i + encodeURIComponent(l)).join("&") : this._isSerializable(s) ? i + encodeURIComponent(JSON.stringify(s)) : i + encodeURIComponent(s);
    }).filter((r) => r).join("&") : "";
  }
}
export {
  g as A
};
