<?php

/**
 * @file
 * Contains ArchibaldClient.
 *
 * This class allows authentication tokens to be re-used, and automatically
 * re-authenticates when receiving a "token expired" (419) or "Unauthorized"
 * (401) responses.
 */

use Educa\DSB\Client\ApiClient\ClientV2;

class ArchibaldClient extends ClientV2 {

  /**
   * Re-authenticate, and refresh the token.
   */
  public function reAuthenticate() {
    $this->authenticate();
    // If the currently installed version of the dsb Client Library is less than
    // 0.19.0, there is no expiration property. Make it expire in 30mins in that
    // case, which should be less than the actual expiration.
    $expires = $this->getTokenExpiresOn();
    cache_set(
      'archibald:auth_token:' . $this->username,
      $this->getTokenKey(),
      'cache',
      !empty($expires) ? strtotime($expires) : REQUEST_TIME + 1800
    );
  }

  /**
   * Set the identification token key.
   *
   * @param string $tokenKey
   */
  public function setTokenKey($tokenKey) {
    $this->tokenKey = $tokenKey;
    return $this;
  }

  /**
   * Get the identification token key.
   *
   * @return string
   */
  public function getTokenKey() {
    return $this->tokenKey;
  }

  /**
   * Set the identification token expiry date.
   *
   * @param string $expire
   */
  public function setTokenExpiresOn($expire) {
    $this->tokenExpiresOn = $tokenExpiresOn;
    return $this;
  }

  /**
   * Get the identification token expiry date.
   *
   * @return string
   */
  public function getTokenExpiresOn() {
    return isset($this->tokenExpiresOn) ? $this->tokenExpiresOn : '';
  }

  /**
   * @{inheritdoc}
   */
  public function post($path, array $options = array()) {
    $response = parent::post($path, $options);
    if (in_array($response->getStatusCode(), array(419, 401))) {
      $this->reAuthenticate();
      $response = parent::post($path, $options);
    }
    return $response;
  }

  /**
   * @{inheritdoc}
   */
  public function get($path, array $options = array()) {
    $response = parent::get($path, $options);
    if (in_array($response->getStatusCode(), array(419, 401))) {
      $this->reAuthenticate();
      $response = parent::get($path, $options);
    }
    return $response;
  }

  /**
   * @{inheritdoc}
   */
  public function put($path, array $options = array()) {
    $response = parent::put($path, $options);
    if (in_array($response->getStatusCode(), array(419, 401))) {
      $this->reAuthenticate();
      $response = parent::put($path, $options);
    }
    return $response;
  }

  /**
   * @{inheritdoc}
   */
  public function delete($path, array $options = array()) {
    $response = parent::delete($path, $options);
    if (in_array($response->getStatusCode(), array(419, 401))) {
      $this->reAuthenticate();
      $response = parent::delete($path, $options);
    }
    return $response;
  }

}
