/**
 * @license
 * Copyright 2020 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import {Aead} from '../aead/internal/aead';
import {InvalidArgumentsException} from '../exception/invalid_arguments_exception';
import {SecurityException} from '../exception/security_exception';
import * as Random from '../subtle/random';

import * as KeyManager from './key_manager';
import {KeysetReader} from './keyset_reader';
import {KeysetWriter} from './keyset_writer';
import * as PrimitiveSet from './primitive_set';
import {PbKeyData, PbKeyMaterialType, PbKeyset, PbKeysetKey, PbKeyStatusType, PbKeyTemplate} from './proto';
import * as Registry from './registry';
import * as Util from './util';

/**
 * Keyset handle provide abstracted access to Keysets, to limit the exposure of
 * actual protocol buffers that hold sensitive key material.
 *
 * @final
 */
export class KeysetHandle {
  private readonly keyset_: PbKeyset;

  constructor(keyset: PbKeyset) {
    Util.validateKeyset(keyset);
    this.keyset_ = keyset;
  }

  /**
   * Returns a primitive that uses key material from this keyset handle. If
   * opt_customKeyManager is defined then the provided key manager is used to
   * instantiate primitives. Otherwise key manager from Registry is used.
   */
  async getPrimitive<P>(
      primitiveType: Util.Constructor<P>,
      opt_customKeyManager?: KeyManager.KeyManager<P>|null): Promise<P> {
    if (!primitiveType) {
      throw new InvalidArgumentsException('primitive type must be non-null');
    }
    const primitiveSet =
        await this.getPrimitiveSet(primitiveType, opt_customKeyManager);
    return Registry.wrap(primitiveSet);
  }

  /**
   * Creates a set of primitives corresponding to the keys with status Enabled
   * in the given keysetHandle, assuming all the correspoding key managers are
   * present (keys with status different from Enabled are skipped). If provided
   * uses customKeyManager instead of registered key managers for keys supported
   * by the customKeyManager.
   *
   * Visible for testing.
   */
  async getPrimitiveSet<P>(
      primitiveType: Util.Constructor<P>,
      opt_customKeyManager?: KeyManager.KeyManager<P>|
      null): Promise<PrimitiveSet.PrimitiveSet<P>> {
    const primitiveSet = new PrimitiveSet.PrimitiveSet<P>(primitiveType);
    const keys = this.keyset_.getKeyList();
    const keysLength = keys.length;
    for (let i = 0; i < keysLength; i++) {
      const key = keys[i];
      if (key.getStatus() === PbKeyStatusType.ENABLED) {
        const keyData = key.getKeyData();
        if (!keyData) {
          throw new SecurityException('Key data has to be non null.');
        }
        let primitive;
        if (opt_customKeyManager &&
            opt_customKeyManager.getKeyType() === keyData.getTypeUrl()) {
          primitive =
              await opt_customKeyManager.getPrimitive(primitiveType, keyData);
        } else {
          primitive = await Registry.getPrimitive<P>(primitiveType, keyData);
        }
        const entry = primitiveSet.addPrimitive(primitive, key);
        if (key.getKeyId() === this.keyset_.getPrimaryKeyId()) {
          primitiveSet.setPrimary(entry);
        }
      }
    }
    return primitiveSet;
  }

  /**
   * Encrypts the underlying keyset with the provided masterKeyAead wnd writes
   * the resulting encryptedKeyset to the given writer which must be non-null.
   *
   *
   */
  async write(writer: KeysetWriter, masterKeyAead: Aead) {
    // TODO implement
    throw new SecurityException('KeysetHandle -- write: Not implemented yet.');
  }

  /**
   * Writes this keyset using `writer` if and only if the keyset doesn't contain
   * any secret key material.
   *
   * This can be used to persist public keysets or envelope encryption keysets.
   * Use `CleartextKeysetHandle` to persist keysets containing secret key
   * material.
   */
  writeNoSecret(writer: KeysetWriter): Uint8Array {
    assertNoSecretKeyMaterial(this.keyset_);
    return writer.encodeBinary(this.keyset_);
  }

  /**
   * Returns the keyset held by this KeysetHandle.
   *
   */
  getKeyset(): PbKeyset {
    return this.keyset_;
  }

  /**
   * If the managed keyset contains private keys, returns a `KeysetHandle` of
   * the public keys.
   */
  getPublicKeysetHandle(): KeysetHandle {
    const publicKeyset = new PbKeyset();
    for (const key of this.keyset_.getKeyList()) {
      publicKeyset.addKey(key.clone().setKeyData(createPublicKeyData(
          nonNull('Key data', key.getKeyData()))));
    }
    publicKeyset.setPrimaryKeyId(this.keyset_.getPrimaryKeyId());
    return new KeysetHandle(publicKeyset);
  }
}

function nonNull<T>(desc: string, value: T|null|undefined): T {
  if (value == null) {
    throw new SecurityException(`${desc} has to be non null.`);
  }
  return value;
}

function createPublicKeyData(privateKeyData: PbKeyData): PbKeyData {
  if (privateKeyData.getKeyMaterialType() !==
      PbKeyData.KeyMaterialType.ASYMMETRIC_PRIVATE) {
    throw new SecurityException('The keyset contains a non-private key');
  }
  return Registry.getPublicKeyData(
      privateKeyData.getTypeUrl(), privateKeyData.getValue_asU8());
}

/**
 * Validates that `keyset` doesn't contain any secret key material.
 *
 * @throws SecurityException if `keyset` contains secret key material.
 */
function assertNoSecretKeyMaterial(keyset: PbKeyset) {
  for (const key of keyset.getKeyList()) {
    const keyData = nonNull('Key data', key.getKeyData());
    if (isSecretKeyMaterialType(keyData.getKeyMaterialType())) {
      throw new SecurityException('Keyset contains secret key material.');
    }
  }
}

/** Returns true if the key material type is secret. */
function isSecretKeyMaterialType(type: PbKeyMaterialType) {
  return type === PbKeyMaterialType.UNKNOWN_KEYMATERIAL ||
      type === PbKeyMaterialType.SYMMETRIC ||
      type === PbKeyMaterialType.ASYMMETRIC_PRIVATE;
}

/**
 * Creates a KeysetHandle from an encrypted keyset obtained via reader, using
 * masterKeyAead to decrypt the keyset.
 *
 *
 */
export async function read(
    reader: KeysetReader, masterKeyAead: Aead): Promise<KeysetHandle> {
  // TODO implement
  throw new SecurityException('KeysetHandle -- read: Not implemented yet.');
}

/**
 * Returns a new KeysetHandle that contains a single new key generated
 * according to keyTemplate.
 *
 *
 */
export async function generateNew(keyTemplate: PbKeyTemplate):
    Promise<KeysetHandle> {
  // TODO(thaidn): move this to a key manager.
  const keyset = await generateNewKeyset_(keyTemplate);
  return new KeysetHandle(keyset);
}

/**
 * Generates a new Keyset that contains a single new key generated
 * according to keyTemplate.
 *
 */
async function generateNewKeyset_(keyTemplate: PbKeyTemplate):
    Promise<PbKeyset> {
  const key = (new PbKeysetKey())
                  .setStatus(PbKeyStatusType.ENABLED)
                  .setOutputPrefixType(keyTemplate.getOutputPrefixType());
  const keyId = generateNewKeyId_();
  key.setKeyId(keyId);
  const keyData = await Registry.newKeyData(keyTemplate);
  key.setKeyData(keyData);
  const keyset = new PbKeyset();
  keyset.addKey(key);
  keyset.setPrimaryKeyId(keyId);
  return keyset;
}

/**
 * Generates a new random key ID.
 *
 * @return The key ID.
 */
function generateNewKeyId_(): number {
  const bytes = Random.randBytes(4);
  let value = 0;
  for (let i = 0; i < bytes.length; i++) {
    value += (bytes[i] & 255) << i * 8;
  }

  // Make sure the key ID is a positive integer smaller than 2^32.
  return Math.abs(value) % 2 ** 32;
}

/**
 * Creates a KeysetHandle from a keyset, obtained via reader, which
 * must contain no secret key material.
 *
 * This can be used to load public keysets or envelope encryption keysets.
 * Users that need to load cleartext keysets can use CleartextKeysetHandle.
 *
 */
export function readNoSecret(reader: KeysetReader): KeysetHandle {
  if (reader === null) {
    throw new SecurityException('Reader has to be non-null.');
  }
  const keyset = reader.read();
  assertNoSecretKeyMaterial(keyset);
  return new KeysetHandle(keyset);
}
