/**
 * Copyright (c) HashiCorp, Inc.
 * SPDX-License-Identifier: BUSL-1.1
 */

import Model, { attr } from '@ember-data/model';
import { findDestination } from 'vault/helpers/sync-destinations';
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
import { withModelValidations } from 'vault/decorators/model-validations';

// Base model for all secret sync destination types
const validations = {
  name: [
    { type: 'presence', message: 'Name is required.' },
    { type: 'containsWhiteSpace', message: 'Name cannot contain whitespace.' },
  ],
};

@withModelValidations(validations)
export default class SyncDestinationModel extends Model {
  @attr('string', { subText: 'Specifies the name for this destination.', editDisabled: true })
  name;

  @attr type;

  @attr('string', {
    subText:
      'Go-template string that indicates how to format the secret name at the destination. The default template varies by destination type but is generally in the form of "vault-{{ .MountAccessor }}-{{ .SecretPath }}" e.g. "vault-kv_9a8f68ad-my-secret-1". Optional.',
  })
  secretNameTemplate;

  @attr('string', {
    editType: 'radio',
    label: 'Secret sync granularity',
    possibleValues: [
      {
        label: 'Secret path',
        subText: 'Sync entire secret contents as a single entry at the destination.',
        value: 'secret-path',
      },
      {
        label: 'Secret key',
        subText: 'Sync each key-value pair of secret data as a distinct entry at the destination.',
        helpText:
          'Only top-level keys will be synced and any nested or complex values will be encoded as a JSON string.',
        value: 'secret-key',
      },
    ],
  })
  granularity; // default value depends on type and is set in create route

  // only present if delete action has been initiated
  @attr('string') purgeInitiatedAt;
  @attr('string') purgeError;

  // findDestination returns static attributes for each destination type
  get icon() {
    return findDestination(this.type)?.icon;
  }

  get typeDisplayName() {
    return findDestination(this.type)?.name;
  }

  get maskedParams() {
    return findDestination(this.type)?.maskedParams;
  }

  @lazyCapabilities(apiPath`sys/sync/destinations/${'type'}/${'name'}`, 'type', 'name') destinationPath;
  @lazyCapabilities(apiPath`sys/sync/destinations/${'type'}/${'name'}/associations/set`, 'type', 'name')
  setAssociationPath;

  get canCreate() {
    return this.destinationPath.get('canCreate') !== false;
  }
  get canDelete() {
    return this.destinationPath.get('canDelete') !== false;
  }
  get canEdit() {
    return this.destinationPath.get('canUpdate') !== false && !this.purgeInitiatedAt;
  }
  get canRead() {
    return this.destinationPath.get('canRead') !== false;
  }
  get canSync() {
    return this.setAssociationPath.get('canUpdate') !== false && !this.purgeInitiatedAt;
  }
}
