"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.currentSiteCloudIdService = exports.CurrentSiteCloudIdService = exports.CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY = exports.CURRENT_SITE_CLOUD_ID_LOCAL_STORAGE_KEY = void 0;
exports.getCachedCurrentSiteCloudIdAndRefresh = getCachedCurrentSiteCloudIdAndRefresh;
exports.getCurrentSiteCloudId = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _storageClient = require("@atlaskit/frontend-utilities/storage-client");
var _linkingCommon = require("@atlaskit/linking-common");
/**
 * Logical key shape matches smart-card storage conventions (see personalization-service). {@link StorageClient}
 * stores rows as `<clientKey>_<itemKey>` with `clientKey === '@atlaskit/smart-card'` and
 * `itemKey === 'site-cloud-id:v1'` (no further scope segments; unlike `pct-map:v1:`, this is a single fixed row).
 */
var SMART_CARD_STORAGE_SCOPE = '@atlaskit/smart-card';
var CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY = exports.CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY = 'site-cloud-id:v1';
var smartCardStorage = new _storageClient.StorageClient(SMART_CARD_STORAGE_SCOPE);

/** Keys written by this service in localStorage when using {@link smartCardStorage}. */
var CURRENT_SITE_CLOUD_ID_LOCAL_STORAGE_KEY = exports.CURRENT_SITE_CLOUD_ID_LOCAL_STORAGE_KEY = "".concat(SMART_CARD_STORAGE_SCOPE, "_").concat(CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY);
var CurrentSiteCloudIdService = exports.CurrentSiteCloudIdService = /*#__PURE__*/function () {
  function CurrentSiteCloudIdService() {
    (0, _classCallCheck2.default)(this, CurrentSiteCloudIdService);
    /**
     * Holds the shared tenant_info work: one in-flight fetch, then (on success) a settled promise for the session cloud
     * id so later callers never trigger another `tenant_info` in the same page lifetime (until {@link clearCache}).
     */
    (0, _defineProperty2.default)(this, "tenantInfoInflightPromise", null);
  }
  return (0, _createClass2.default)(CurrentSiteCloudIdService, [{
    key: "readStoredCloudId",
    value: function readStoredCloudId() {
      try {
        var cloudId = smartCardStorage.getItem(CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY);
        if (typeof cloudId !== 'string' || !cloudId || cloudId === 'undefined') {
          return undefined;
        }
        return cloudId;
      } catch (_unused) {
        return undefined;
      }
    }
  }, {
    key: "writeStoredCloudId",
    value: function writeStoredCloudId(cloudId) {
      if (!cloudId) {
        return;
      }
      try {
        smartCardStorage.setItemWithExpiry(CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY, cloudId);
      } catch (_unused2) {
        // Quota, private-mode, SSR, etc. — same intent as personalization-service.
      }
    }
  }, {
    key: "ensureTenantInfoInflightStarted",
    value: function ensureTenantInfoInflightStarted(baseUriWithNoTrailingSlash) {
      var _this = this;
      if (this.tenantInfoInflightPromise !== null) {
        return;
      }
      this.tenantInfoInflightPromise = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
        var response, cloudId;
        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) switch (_context.prev = _context.next) {
            case 0:
              _context.prev = 0;
              _context.next = 3;
              return (0, _linkingCommon.request)('get', baseUriWithNoTrailingSlash + '/_edge/tenant_info');
            case 3:
              response = _context.sent;
              cloudId = response === null || response === void 0 ? void 0 : response.cloudId;
              if (cloudId) {
                _this.writeStoredCloudId(cloudId);
              }
              return _context.abrupt("return", cloudId ? cloudId : _this.readStoredCloudId());
            case 9:
              _context.prev = 9;
              _context.t0 = _context["catch"](0);
              _this.tenantInfoInflightPromise = null;
              return _context.abrupt("return", _this.readStoredCloudId());
            case 13:
            case "end":
              return _context.stop();
          }
        }, _callee, null, [[0, 9]]);
      }))();
    }

    /**
     * Returns the currently cached cloud id synchronously and starts a background refresh.
     * The refresh result is persisted for future calls but is not awaited by this call.
     */
  }, {
    key: "getCachedCloudIdAndRefresh",
    value: function getCachedCloudIdAndRefresh() {
      this.ensureTenantInfoInflightStarted('');
      return this.readStoredCloudId();
    }

    /** Writes tenant cloud id for tests or callers that intentionally warm storage before edge resolves. */
  }, {
    key: "persistStoredCloudId",
    value: function persistStoredCloudId(cloudId) {
      this.writeStoredCloudId(cloudId);
    }

    /**
     * When local storage already has a tenant cloud id, it is returned immediately; a background tenant_info refresh
     * is still kicked off unless one is already in flight.
     *
     * Without storage, this awaits the deduped in-flight tenant_info (first concurrent caller chooses the URL;
     * all share one promise regardless of subsequent `baseUriWithNoTrailingSlash`).
     *
     * On network success with no cloud id, or on failure: falls back via {@link readStoredCloudId}.
     */
  }, {
    key: "get",
    value: (function () {
      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
        var baseUriWithNoTrailingSlash,
          fromStorage,
          _args2 = arguments;
        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) switch (_context2.prev = _context2.next) {
            case 0:
              baseUriWithNoTrailingSlash = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : '';
              fromStorage = this.readStoredCloudId();
              this.ensureTenantInfoInflightStarted(baseUriWithNoTrailingSlash);
              if (!fromStorage) {
                _context2.next = 5;
                break;
              }
              return _context2.abrupt("return", fromStorage);
            case 5:
              return _context2.abrupt("return", this.tenantInfoInflightPromise);
            case 6:
            case "end":
              return _context2.stop();
          }
        }, _callee2, this);
      }));
      function get() {
        return _get.apply(this, arguments);
      }
      return get;
    }() /** Clears session pin and persisted storage so the next {@link get} is a fresh tenant_info fetch. */)
  }, {
    key: "clearCache",
    value: function clearCache() {
      this.tenantInfoInflightPromise = null;
      smartCardStorage.removeItem(CURRENT_SITE_CLOUD_ID_STORAGE_ITEM_KEY);
    }
  }]);
}();
var currentSiteCloudIdService = exports.currentSiteCloudIdService = new CurrentSiteCloudIdService();

/**
 * Resolves the current site cloud id through the module-level {@link currentSiteCloudIdService}.
 * Returns a stored cloud id immediately when one exists; otherwise waits for the shared
 * `tenant_info` request and persists the result for subsequent cached reads.
 */
var getCurrentSiteCloudId = exports.getCurrentSiteCloudId = function getCurrentSiteCloudId() {
  var baseUriWithNoTrailingSlash = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  return currentSiteCloudIdService.get(baseUriWithNoTrailingSlash);
};

/**
 * Reads the current site cloud id from browser storage (the `site-cloud-id:v1` row) via the
 * module-level {@link currentSiteCloudIdService} singleton, without awaiting network work.
 * Calling this also starts the shared `tenant_info` refresh in the background when one is not
 * already running, so a later call can observe a refreshed value when available.
 */
function getCachedCurrentSiteCloudIdAndRefresh() {
  return currentSiteCloudIdService.getCachedCloudIdAndRefresh();
}