import { EncryptionService } from "./EncryptionService";
import * as sjcl from "sjcl";
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
import PromiseWorker from "promise-worker";
export class SJCLEncryptionService implements EncryptionService {
  private _params: sjcl.SjclCipherParams = {
    mode: "gcm",
    ts: 128,
    adata: "",
    iter: 10000,
  };
  private readonly _promiseWorker: PromiseWorker;

  constructor(promiseWorker: PromiseWorker) {
    this._promiseWorker = promiseWorker;
  }

  public encrypt(passphrase: string, plainText: string): MessageCipherDTO {
    const fn = () => {
      // @ts-ignore
      const cipher = sjcl.encrypt(passphrase, plainText, this._params);
      return (cipher as unknown) as string;
    };
    return JSON.parse(fn());
  }

  public decrypt(passphrase: string, cipher: MessageCipherDTO): string {
    return sjcl.decrypt(passphrase, JSON.stringify(cipher));
  }

  public async decryptAsPromise(
    passphrase: string,
    cipher: MessageCipherDTO
  ): Promise<string> {
    const decrypted = await this._promiseWorker.postMessage<
      string,
      { passphrase: string; cipher: MessageCipherDTO }
    >({ passphrase: passphrase, cipher: cipher });
    return decrypted;
  }
}
