//--------------------------------------------------------------------------------------------------
// Copyright (c) id3 Technologies
// All Rights Reserved.
//--------------------------------------------------------------------------------------------------
// ignore_for_file: unused_import
import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data';
import 'package:ffi/ffi.dart';
import 'bioseal_sdk_generated_bindings.dart';
import 'bioseal_native.dart';

import '../id3_bioseal.dart';

final _finalizer = NativeFinalizer(biosealSDK.addresses.id3BiosealUserAuthentication_Dispose.cast());

/// Represents the user authentication parameters.
class UserAuthentication implements Finalizable {
  /// Native handle.
  late Pointer<Pointer<id3BiosealUserAuthentication>> _pHandle;
  bool _disposable = true;

  /// Gets the native handle.
  /// return The native handle.
  Pointer<id3BiosealUserAuthentication> get handle => _pHandle.value;

  /// Creates a new instance of the UserAuthentication class.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  UserAuthentication() {
    _pHandle = calloc();
    try {
      var err = biosealSDK.id3BiosealUserAuthentication_Initialize(_pHandle);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      _finalizer.attach(this, _pHandle.cast(), detach: this);
    } finally {}
  }

  /// Creates a new instance of the UserAuthentication class.
  ///
  /// param handle     Handle to the UserAuthentication.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  UserAuthentication.fromHandle(Pointer<id3BiosealUserAuthentication> handle) {
    _pHandle = calloc();
    _pHandle.value = handle;
    _disposable = false;
  }

  /// Releases all resources used by this UserAuthentication.
  void dispose() {
    if (_disposable) {
      biosealSDK.id3BiosealUserAuthentication_Dispose(_pHandle);
      calloc.free(_pHandle);
      _finalizer.detach(this);
    }
  }


  ///
  /// The user authentication method.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  UserAuthenticationMethod get method => getMethod();

  ///
  /// The name of the payload field containing the password value.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get passwordFieldName => getPasswordFieldName();

  ///
  /// The hash algorithm used to protect the password value. Possible values are: Sha256, Sha384, Sha512.
  ///
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String get passwordHashAlgorithm => getPasswordHashAlgorithm();

  // Public methods
  /// Gets the the user authentication method.
  ///
  /// return The user authentication method.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  UserAuthenticationMethod getMethod() {
    Pointer<Int32> pMethod = calloc();
    try {
      var err = biosealSDK.id3BiosealUserAuthentication_GetMethod(_pHandle.value, pMethod);
      if (err != BiosealError.success.value) {
        throw BiosealException(err);
      }
      final vMethod = UserAuthenticationMethodX.fromValue(pMethod.value);
      return vMethod;
    } finally {
      calloc.free(pMethod);
    }
  }

  /// Gets the the name of the payload field containing the password value.
  ///
  /// return The name of the payload field containing the password value.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getPasswordFieldName() {
    Pointer<Char> pPasswordFieldName = nullptr;
    Pointer<Int> pPasswordFieldNameSize = calloc.allocate(1);
    pPasswordFieldNameSize[0] = -1;
    try {
      var err = biosealSDK.id3BiosealUserAuthentication_GetPasswordFieldName(_pHandle.value, pPasswordFieldName, pPasswordFieldNameSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pPasswordFieldName = calloc.allocate(pPasswordFieldNameSize.value);
        err = biosealSDK.id3BiosealUserAuthentication_GetPasswordFieldName(_pHandle.value, pPasswordFieldName, pPasswordFieldNameSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vPasswordFieldName = utf8.decode(Uint8List.fromList(pPasswordFieldName.cast<Uint8>().asTypedList(pPasswordFieldNameSize.value)));
      return vPasswordFieldName;
    } finally {
      calloc.free(pPasswordFieldName);
      calloc.free(pPasswordFieldNameSize);
    }
  }

  /// Gets the the hash algorithm used to protect the password value. Possible values are: Sha256, Sha384, Sha512.
  ///
  /// return The hash algorithm used to protect the password value. Possible values are: Sha256, Sha384, Sha512.
  /// throws BiosealException An error has occurred during Bioseal Library execution.
  String getPasswordHashAlgorithm() {
    Pointer<Char> pPasswordHashAlgorithm = nullptr;
    Pointer<Int> pPasswordHashAlgorithmSize = calloc.allocate(1);
    pPasswordHashAlgorithmSize[0] = -1;
    try {
      var err = biosealSDK.id3BiosealUserAuthentication_GetPasswordHashAlgorithm(_pHandle.value, pPasswordHashAlgorithm, pPasswordHashAlgorithmSize);
      if (err == BiosealError.insufficientBuffer.value) {
        pPasswordHashAlgorithm = calloc.allocate(pPasswordHashAlgorithmSize.value);
        err = biosealSDK.id3BiosealUserAuthentication_GetPasswordHashAlgorithm(_pHandle.value, pPasswordHashAlgorithm, pPasswordHashAlgorithmSize);
        if (err != BiosealError.success.value) {
          throw BiosealException(err);
        }
      }
      final vPasswordHashAlgorithm = utf8.decode(Uint8List.fromList(pPasswordHashAlgorithm.cast<Uint8>().asTypedList(pPasswordHashAlgorithmSize.value)));
      return vPasswordHashAlgorithm;
    } finally {
      calloc.free(pPasswordHashAlgorithm);
      calloc.free(pPasswordHashAlgorithmSize);
    }
  }

}

