import * as webcrypto from "webcrypto";

const crypto = webcrypto;
const algorithm = "aes-256-ctr";
const sessionStorage = window.sessionStorage;

interface Options {
  password?: string;
}

export class StorageFacade {
  async set(key: string, value: string, options?: Options) {
    if (options && options.password) {
      let encryptedValue = this.encryptWithPassword(value, options.password);
      sessionStorage.setItem(key, encryptedValue);
    } else {
      sessionStorage.setItem(key, value);
    }
  }

  async get(key: string, options?: Options): Promise<string> {
    if (options && options.password) {
      let encryptedValue = await sessionStorage.getItem(key);

      return this.decryptWithPassword(encryptedValue, options.password);
    } else {
      return await sessionStorage.getItem(key);
    }
  }

  async exists(key: string) {
    return (await sessionStorage.getItem(key)) ? true : false;
  }

  async delete(key: string) {
    sessionStorage.removeItem(key);
  }

  private encryptWithPassword(text: string, password: string) {
    var cipher = crypto.createCipher(algorithm, password);
    var encrypted = cipher.update(text, "utf8", "hex");
    encrypted += cipher.final("hex");

    return encrypted;
  }

  private decryptWithPassword(text: string, password: string): string {
    var decipher = crypto.createDecipher(algorithm, password);
    var decrypted = decipher.update(text, "hex", "utf8");
    decrypted += decipher.final("utf8");

    return decrypted;
  }
}
