import ChildSelectorComponent from './child-selector';
import { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import updateArrayObject from 'consul-ui/utils/update-array-object';

const ERROR_PARSE_RULES = 'Failed to parse ACL rules';
const ERROR_INVALID_POLICY = 'Invalid service policy';
const ERROR_NAME_EXISTS = 'Invalid Policy: A Policy with Name';

export default ChildSelectorComponent.extend({
  repo: service('repository/policy/component'),
  datacenterRepo: service('repository/dc/component'),
  name: 'policy',
  type: 'policy',
  classNames: ['policy-selector'],
  init: function() {
    this._super(...arguments);
    const source = get(this, 'source');
    if (source) {
      const event = 'save';
      this.listen(source, event, e => {
        this.actions[event].bind(this)(...e.data);
      });
    }
  },
  reset: function(e) {
    this._super(...arguments);
    set(this, 'isScoped', false);
    set(this, 'datacenters', get(this, 'datacenterRepo').findAll());
  },
  refreshCodeEditor: function(e, target) {
    const selector = '.code-editor';
    get(this, 'dom')
      .component(selector, target)
      .didAppear();
  },
  error: function(e) {
    const item = get(this, 'item');
    const err = e.error;
    if (typeof err.errors !== 'undefined') {
      const error = err.errors[0];
      let prop = 'Rules';
      let message = error.detail;
      switch (true) {
        case message.indexOf(ERROR_PARSE_RULES) === 0:
        case message.indexOf(ERROR_INVALID_POLICY) === 0:
          prop = 'Rules';
          message = error.detail;
          break;
        case message.indexOf(ERROR_NAME_EXISTS) === 0:
          prop = 'Name';
          message = message.substr(ERROR_NAME_EXISTS.indexOf(':') + 1);
          break;
      }
      if (prop) {
        item.addError(prop, message);
      }
    } else {
      // TODO: Conponents can't throw, use onerror
      throw err;
    }
  },
  actions: {
    loadItem: function(e, item, items) {
      const target = e.target;
      // the Details expander toggle, only load on opening
      if (target.checked) {
        const value = item;
        this.refreshCodeEditor(e, target.parentNode);
        if (get(item, 'template') === 'service-identity') {
          return;
        }
        // potentially the item could change between load, so we don't check
        // anything to see if its already loaded here
        const repo = get(this, 'repo');
        // TODO: Temporarily add dc here, will soon be serialized onto the policy itself
        const dc = get(this, 'dc');
        const slugKey = repo.getSlugKey();
        const slug = get(value, slugKey);
        updateArrayObject(items, repo.findBySlug(slug, dc), slugKey, slug);
      }
    },
  },
});