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

import Component from '@ember/component';
import { set } from '@ember/object';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';

const BASE_64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gi;

export default Component.extend({
  'data-test-pgp-file': true,
  attributeBindings: ['data-test-pgp-file'],
  classNames: ['box', 'is-fullwidth', 'is-marginless', 'is-shadowless'],
  key: null,
  index: null,
  onChange: () => {},

  /*
   * @public
   * @param String
   * Text to use as the label for the file input
   * If null, a default will be rendered
   */
  label: null,

  /*
   * @public
   * @param String
   * Text to use as help under the file input
   * If null, a default will be rendered
   */
  fileHelpText: null,

  /*
   * @public
   * @param String
   * Text to use as help under the textarea in text-input mode
   * If null, a default will be rendered
   */
  textareaHelpText: null,

  readFile(file) {
    const reader = new FileReader();
    reader.onload = () => this.setPGPKey.perform(reader.result, file.name);
    // this gives us a base64-encoded string which is important in the onload
    reader.readAsDataURL(file);
  },

  setPGPKey: task(
    waitFor(function* (dataURL, filename) {
      const b64File = dataURL.split(',')[1].trim();
      const decoded = atob(b64File).trim();

      // If a b64-encoded file was uploaded, then after decoding, it
      // will still be b64.
      // If after decoding it's not b64, we want
      // the original as it was only encoded when we used `readAsDataURL`.
      const fileData = decoded.match(BASE_64_REGEX) ? decoded : b64File;
      yield this.onChange(this.index, { value: fileData, filename: filename });
    })
  ),

  actions: {
    pickedFile(e) {
      const { files } = e.target;
      if (!files.length) {
        return;
      }
      for (let i = 0, len = files.length; i < len; i++) {
        this.readFile(files[i]);
      }
    },
    updateData(e) {
      const key = this.key;
      set(key, 'value', e.target.value);
      this.onChange(this.index, this.key);
    },
    clearKey() {
      this.onChange(this.index, { value: '' });
    },
  },
});
