/**
 * Copyright IBM Corp. 2016, 2025
 * SPDX-License-Identifier: BUSL-1.1
 */

import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { withFormFields } from 'vault/decorators/model-form-fields';
import sinon from 'sinon';

module('Unit | Decorators | ModelFormFields', function (hooks) {
  setupApplicationTest(hooks);

  hooks.beforeEach(function () {
    this.spy = sinon.spy(console, 'error');
    this.store = this.owner.lookup('service:store');
  });
  hooks.afterEach(function () {
    this.spy.restore();
  });

  test('it should warn when applying decorator to class that does not extend Model', function (assert) {
    @withFormFields()
    class Foo {} // eslint-disable-line
    const message =
      'withFormFields decorator must be used on instance of ember-data Model class. Decorator not applied to returned class';
    assert.ok(this.spy.calledWith(message), 'Error is printed to console');
  });

  test('it returns allFields when arguments not provided', function (assert) {
    assert.expect(1);
    // test by instantiating a record that uses this decorator
    const record = this.store.createRecord('totp-key');
    assert.deepEqual(
      record.allFields,
      [
        {
          name: 'backend',
          options: { readOnly: true },
          type: 'string',
        },
        {
          name: 'name',
          options: {
            subText: 'Specifies the name for this key.',
          },
          type: 'string',
        },
        {
          name: 'accountName',
          options: {
            subText: 'The name of the account associated with the key. Required for keys generated by Vault.',
          },
          type: 'string',
        },
        {
          name: 'algorithm',
          options: { possibleValues: ['SHA1', 'SHA256', 'SHA512'], defaultValue: 'SHA1' },
          type: 'string',
        },
        {
          name: 'digits',
          options: { possibleValues: [6, 8], defaultValue: 6 },
          type: 'number',
        },
        {
          name: 'issuer',
          options: {
            subText: `The name of the key's issuing organization. Required for keys generated by Vault.`,
          },
          type: 'string',
        },
        {
          name: 'period',
          options: {
            editType: 'ttl',
            helperTextEnabled: 'How long each generated TOTP is valid.',
            defaultValue: 30,
          },
          type: undefined,
        },
        {
          name: 'generate',
          options: {
            label: 'Key Provider',
            defaultValue: true,
            editType: 'radio',
            possibleValues: ['Vault', 'Other service'],
            fieldValue: 'generateString',
            subText: 'Specifies if the key should be generated by Vault or passed from another service.',
          },
          type: undefined,
        },
        {
          name: 'keySize',
          options: { defaultValue: 20 },
          type: 'number',
        },
        {
          name: 'skew',
          options: { possibleValues: [0, 1], defaultValue: 1 },
          type: 'number',
        },
        {
          name: 'exported',
          options: {
            editType: 'toggleButton',
            defaultValue: true,
            helperTextDisabled: 'Vault will not return QR code and url upon key creation.',
            helperTextEnabled: 'QR code and URL will be returned upon generating a key.',
          },
          type: 'boolean',
        },
        {
          name: 'qrSize',
          options: { label: 'QR size', defaultValue: 200 },
          type: 'number',
        },
        {
          name: 'url',
          options: {
            label: 'URL',
            helpText:
              'If a URL is provided the other fields can be left empty. E.g. otpauth://totp/Vault:test@test.com?secret=Y64VEVMBTSXCYIWRSHRNDZW62MPGVU2G&issuer=Vault',
            subText: 'The TOTP key url string that can be used to configure a key.',
          },
          type: 'string',
        },
        {
          name: 'key',
          options: {
            subText: 'The root key used to generate a TOTP code.',
          },
          type: 'string',
        },
        {
          name: 'barcode',
          options: { readOnly: true },
          type: 'string',
        },
      ],
      'allFields set on Model class'
    );
  });

  test('it should set formFields prop on Model class', function (assert) {
    // this model uses withFormFields
    const record = this.store.createRecord('clients/config');
    assert.deepEqual(
      record.formFields,
      [
        {
          name: 'enabled',
          options: {},
          type: 'string',
        },
        {
          name: 'retentionMonths',
          options: {
            label: 'Retention period',
            subText: 'The number of months of activity logs to maintain for client tracking.',
          },
          type: 'number',
        },
      ],
      'formFields set on Model class'
    );
  });

  test('it should set formFieldGroups on Model class', function (assert) {
    // this model uses withFormFields with groups
    const record = this.store.createRecord('ldap/config');
    const groups = record.formFieldGroups.map((group) => Object.keys(group)[0]);
    assert.deepEqual(
      groups,
      ['default', 'TLS options', 'More options'],
      'formFieldGroups set on Model class with correct group labels'
    );
  });
});
