import {
  AESCipherCBC,
  AESCipherGCM,
  AESCipherSIVDeterministic,
  AESCipherSIVNonce96,
} from './cipher/aes';
import { Ed25519DS } from './ds/ec';
import { AbstractCryptoBase } from './interface';
import { Curve25519SharedSecretGenerator } from './key/dh';
import { Curve25519KeyGenerator, Ed25519KeyGenerator } from './key/ec';
import { HKDFKeyGeneratorV1, HKDFKeyGeneratorV2 } from './key/kdf';
import { RandomKeyGenerator128, RandomKeyGenerator256, RandomKeyGenerator512 } from './key/random';

/**
 * This is mostly available to facilitate testing and development. Most of the time the different base
    constructs will be used directly instead.
 */
export class CryptoBaseRegistry {
  protected _registry;

  public constructor(cbs: AbstractCryptoBase[]) {
    this._registry = {};
    cbs.forEach((cb) => {
      let d = cb.describe();
      if (d in this._registry) {
        throw 'Crypto base conflict';
      }
      this._registry[d] = cb;
    });
  }

  public get(name) {
    return this._registry.get(name);
  }

  public describe(): Object {
    return { cbs: this._registry.keys().sort() };
  }
}

export let CRYPTO_BASE_REGISTRY = new CryptoBaseRegistry([
  // key related crypto bases
  Ed25519KeyGenerator,
  Curve25519KeyGenerator,
  Curve25519SharedSecretGenerator,
  HKDFKeyGeneratorV1,
  HKDFKeyGeneratorV2,
  RandomKeyGenerator128,
  RandomKeyGenerator256,
  RandomKeyGenerator512,
  // cipher crypto bases
  AESCipherSIVNonce96,
  AESCipherSIVDeterministic,
  AESCipherGCM,
  AESCipherCBC,
  // digital signature crypto bases
  Ed25519DS,
]);
