cqi.models.resource = {};


/**
 * A base class for representing a single object on the server.
 */
cqi.models.resource.Model = class Model {
  /**
   * @param {object} attrs
   * @param {cqi.CQiClient} client
   * @param {cqi.models.resource.Collection} collection
   */
  constructor(attrs, client, collection) {
     /**
      * A client pointing at the server that this object is on.
      *
      * @type {cqi.CQiClient}
      */
    this.client = client;
     /**
      * The collection that this model is part of.
      *
      * @type {cqi.models.resource.Collection}
      */
    this.collection = collection;
     /**
      * The raw representation of this object from the API
      *
      * @type {object} 
      */
    this.attrs = attrs;
  }

  /**
   * @returns {string}
   */
  get apiName() {
    throw new Error('Not implemented');
  }

  /**
   * @returns {Promise<void>}
   */
  async reload() {
    this.attrs = await this.collection.get(this.apiName).attrs;
  }
};


/**
 * A base class for representing all objects of a particular type on the server.
 */
cqi.models.resource.Collection = class Collection {
   /** 
    * The type of object this collection represents, set by subclasses
    * 
    * @type {typeof cqi.models.resource.Model}
    */
  static model;

  /**
   * @param {cqi.CQiClient} client
   */
  constructor(client) {
     /**
      * A client pointing at the server that this object is on.
      *
      * @type {cqi.CQiClient}
      */
     this.client = client;
  }

  async list() {
    throw new Error('Not implemented');
  }

  async get() {
    throw new Error('Not implemented');
  }

  /**
   * Create a model from a set of attributes.
   * 
   * @param {object} attrs
   * @returns {cqi.models.resource.Model}
   */
  prepareModel(attrs) {
    return new this.constructor.model(attrs, this.client, this);
  }
};