import { setupRenderingTest } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

import { deprecate } from '@ember/application/deprecations';
import Component from '@ember/component';
import { computed } from '@ember/object';
import { readOnly } from '@ember/object/computed';
import { htmlSafe } from '@ember/string';
import { render, getContext } from '@ember/test-helpers';

import { task } from 'ember-concurrency';
import { pluralize } from 'ember-inflector';

/**
 * This should be used as a replacement for `setupRenderingTest()`
 * and additionally sets up a few other things that help when
 * testing cards.
 */
export function setupCardTest(hooks) {
  setupRenderingTest(hooks);
  setupCardTestComponent(hooks);
  setupURLs(hooks);
}

// This is a workaround for https://github.com/intercom/ember-href-to/issues/94
// We use href-to internally in cardstack-url. So if you want to generate a link
// in a rendering test, you need use this.
export function setupURLs(hooks) {
  hooks.beforeEach(function() {
    this.owner.lookup('router:main').setupRouter()
  })
}

/**
 * Allows access to the `cardstack-tools` service during tests.
 *
 * Examples:
 *
 * ```js
 * assert.strictEqual(getTools().active, true);
 * getTools().setActive(false);
 * ```
 */
export function getTools() {
  return getContext().owner.lookup('service:cardstack-tools');
}

export function findCard(type, id, format='isolated') {
  return getContext().owner.lookup('service:cardstackData').load(type, id, format);
}

export function getSpaceForCard(type, id) {
  return getContext().owner.lookup('service:store').findRecord('space', `/${pluralize(type)}/${id}`);
}

export function renderCard(type, id, format, options = {}) {
  let deprecation_message = `\`renderCard()\` was deprecated in favor using the regular \`render()\` test helper with the \`cardstack-card-test\` component:

    await render(hbs\`{{cardstack-card-test "${type}" "${id}" format="${format}"}}\`);

When using the above code make sure to use the \`setupCardTest(hooks)\` test helper, instead of \`setupRenderingTest(hooks)\``;

  deprecate(deprecation_message, false, {
    id: '@cardstack-test-support-render-card',
    until: '0.13.0',
  });

  return getSpaceForCard(type, id).then(space => {
    let context = getContext();
    let card = space.get('primaryCard');
    let params = space.get('params');
    context.set('card', card);
    context.set('format', format);
    context.set('params', Object.assign({}, params, options.params || {}));

    if (options.width) {
      context.set('widthStyle', htmlSafe(`width: ${options.width}`));
      return render(hbs`
      <div style="{{widthStyle}}">
        {{cardstack-content content=card format=format params=params }}
      </div>`);
    } else {
      return render(hbs`{{cardstack-content content=card format=format params=params }}`);
    }
  });
}

/**
 * This sets up a `cardstack-card-test` component that can be use to render
 * cards in the QUnit test fixture:
 *
 * ```js
 * await render(hbs`{{cardstack-card-test "works-detail" 123 format="embedded"}}`);
 * ```
 *
 * The positional parameters are the card name and the ID. The component also
 * supports optional `format` and `params` parameters.
 */
export function setupCardTestComponent(hooks) {
  hooks.beforeEach(function() {
    let CardTestComponent = Component.extend({
      tagName: '',

      // inputs
      type: null,
      id: null,
      format: 'isolated',
      params: null,

      // filled by `getSpaceForCardTask`
      space: null,

      // derived data
      card: readOnly('space.primaryCard'),
      _params: computed('space', 'params', function() {
        Object.assign({}, this.get('space.params'), this.params)
      }),

      getSpaceForCardTask: task(function*() {
        let space = yield getSpaceForCard(this.type, this.id);
        this.set('space', space);
      }).on('didInsertElement').cancelOn('willDestroyElement'),
    });

    CardTestComponent.reopenClass({
      positionalParams: ['type', 'id'],
    });

    this.owner.register('component:cardstack-card-test', CardTestComponent);

    this.owner.register('template:components/cardstack-card-test',
      hbs`{{#if card}}{{cardstack-content content=card format=format params=params}}{{/if}}`);
  });
}

@@ -355,16 +355,25 @@
 tContext
+, settled
  %7D from 
@@ -1371,24 +1371,410 @@
 tools');%0A%7D%0A%0A
+/**%0A * Opens the tools, if available.%0A */%0Aexport async function openTools() %7B%0A  let tools = getTools();%0A%0A  if (!tools.available) %7B%0A    throw new Error('The editor tools are not available.');%0A  %7D%0A%0A  tools.setActive(true);%0A%0A  await settled();%0A%7D%0A%0A/**%0A * Closes the tools.%0A */%0Aexport async function closeTools() %7B%0A  let tools = getTools();%0A%0A  tools.setActive(false);%0A%0A  await settled();%0A%7D%0A%0A
 export funct

Add `open/closeTools()` helpers