import { AbstractAccountKeyring, AbstractSelfAccountKeyring } from '../keyring/account_base';
import { AbstractRoomKeyring } from '../keyring/room_base';
import { TimestampWindowCalculator } from './timestamp';
import { HKDFKeyGeneratorV1 } from '../base/key/kdf';
import { Curve25519SharedSecretGenerator } from '../base/key/dh';
import { concatByteArray } from '../utility';

// TODOIMP
export let TS_WINDOW_V1 = new TimestampWindowCalculator(60 * 60 * 24 * 14, 2 * 60 * 60); // 2 weeks with 2 hour overlap

/**
 * Freeze the HKDF construct for account secret and salt usage.
 */
export class AccountMasterDeriveKeyV1 {
  public static derive_key(
    self_kr: AbstractSelfAccountKeyring,
    info: Uint8Array,
    cache: boolean = true,
    size: number = 64
  ): Promise<Uint8Array> {
    return HKDFKeyGeneratorV1.new_key(
      size,
      self_kr.get_secret_key(AbstractSelfAccountKeyring.MASTER),
      concatByteArray(HKDFKeyGeneratorV1.SALTS[0], self_kr.id),
      info
    );
  }
}

/**
 * Freeze the HKDF construct for account-pair shared-secret and salt usage.
 */
export class AccountPairDeriveKeyV1 {
  public static derive_key(
    self_kr: AbstractSelfAccountKeyring,
    peer_kr: AbstractAccountKeyring,
    info: Uint8Array,
    cache: boolean = true
  ): Promise<Uint8Array> {
    return HKDFKeyGeneratorV1.new_key(
      64,
      Curve25519SharedSecretGenerator.new_key(
        self_kr.get_secret_key(AbstractSelfAccountKeyring.CURVE25519),
        peer_kr.get_public_key(AbstractSelfAccountKeyring.CURVE25519)
      ),
      concatByteArray(HKDFKeyGeneratorV1.SALTS[0], self_kr.ordered_ids(peer_kr)),
      info
    );
  }
}

/**
 * Freeze the HKDF construct for room-pinned key and salt usage.
 */
export class RoomPinnedDeriveKeyV1 {
  public static derive_key(
    room_kr: AbstractRoomKeyring,
    info: Uint8Array,
    cache: boolean = true
  ): Promise<Uint8Array> {
    return HKDFKeyGeneratorV1.new_key(
      64,
      room_kr.get_key(AbstractRoomKeyring.PINNED),
      concatByteArray(HKDFKeyGeneratorV1.SALTS[0], room_kr.id),
      info
    );
  }
}
