// Manages web push subscriptions
//
function urlBase64ToUint8Array(base64String) {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");

  const rawData = window.atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

// In local storage: Map of sid -> { endpoint: "<endpoint>" }
// If entry exists, it means there is a subscription to that room, wired to that endpoint.
const LOCAL_STORE_KEY = "___hubs_subscriptions";

export default class Subscriptions {
  constructor(hubId) {
    this.hubId = hubId;
  }

  setHubChannel = hubChannel => {
    this.hubChannel = hubChannel;
  };

  setRegistration = registration => {
    this.registration = registration;
  };

  setVapidPublicKey = vapidPublicKey => {
    this.vapidPublicKey = vapidPublicKey;
  };

  getSubscriptionsFromStorage = () => {
    return JSON.parse(localStorage.getItem(LOCAL_STORE_KEY) || "{}");
  };

  setSubscriptionsToStorage = subscriptions => {
    return localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify(subscriptions));
  };

  isSubscribed = () => {
    if (typeof this._isSubscribed === "undefined") {
      this._isSubscribed = !!this.getSubscriptionsFromStorage()[this.hubId];
    }

    return this._isSubscribed;
  };

  toggle = async () => {
    const subscriptions = this.getSubscriptionsFromStorage();

    if (this.isSubscribed()) {
      const endpoint = subscriptions[this.hubId].endpoint;
      console.log("De-register push subscription with reticulum for endpoint " + endpoint);

      delete subscriptions[this.hubId];

      if (Object.keys(subscriptions).length === 0) {
        console.log("Remove push subscription from browser");
      }
    } else {
      let subscription = await this.registration.pushManager.getSubscription();

      if (!subscription) {
        const convertedVapidKey = urlBase64ToUint8Array(this.vapidPublicKey);

        subscription = await this.registration.pushManager.subscribe({
          userVisibleOnly: true,
          applicationServerKey: convertedVapidKey
        });
      }

      subscriptions[this.hubId] = { endpoint: subscription.endpoint };
      console.log("Register push subscription with reticulum");
    }

    delete this._isSubscribed;
    this.setSubscriptionsToStorage(subscriptions);
  };
}