<?php

namespace Drupal\pagedesigner\Plugin\rest\resource;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Language\LanguageInterface;
use Drupal\node\Entity\Node;
use Drupal\rest\ModifiedResourceResponse;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Locking endpoint.
 *
 * Provides methods for locking and unlocking pages.
 *
 * @RestResource(
 *   id = "pagdesigner_lock",
 *   label = @Translation("Pagedesigner locks"),
 *   uri_paths = {
 *      "canonical" = "/pagedesigner/lock/{id}",
 *      "create" = "/pagedesigner/lock"
 *   }
 * )
 */
class LockResource extends ResourceBase {

  /**
   * Get lock info.
   *
   * Returns info about the lock on a certain node.
   *
   * @param int $id
   *   The node id.
   *
   * @return \Drupal\rest\ResourceResponse
   *   The responce containing the info.
   */
  public function get($id = NULL) {
    $language = \Drupal::languageManager()->getcurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
    $locker = \Drupal::service('pagedesigner.locker');
    $response = new ResourceResponse([FALSE]);

    $node = Node::load($id);
    if ($node->hasTranslation($language)) {
      $node = $node->getTranslation($language);
      $locker->setEntity($node);

      $response = new ResourceResponse([$locker->hasLock()]);
    }
    $response->addCacheableDependency(['cache' => ['max-age' => 0]]);
    return $response;
  }

  /**
   * Create new lock.
   *
   * Create a new lock on the node.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   *
   * @return \Drupal\rest\ResourceResponse
   *   Containing either true on success of info about the existing lock.
   */
  public function post(Request $request) {
    $requestContent = Json::decode($request->getContent());
    $language = \Drupal::languageManager()->getcurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
    $response = new ResourceResponse([FALSE]);
    $response->addCacheableDependency(['cache' => ['max-age' => 0]]);

    $nodeId = $requestContent['nodeId'];
    $identifier = $requestContent['identifier'];
    $node = Node::load($nodeId);
    if ($node->hasTranslation($language)) {
      $node = $node->getTranslation($language);
      $locker = \Drupal::service('pagedesigner.locker')->setEntity($node);
      if ($locker->acquire($identifier)) {
        $response = new ModifiedResourceResponse([TRUE, $identifier]);
      }
    }
    return $response;
  }

  /**
   * Update a lock.
   *
   * Update a lock on the node.
   *
   * @param int $id
   *   The node id.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   *
   * @return \Drupal\rest\ResourceResponse
   *   Containing either true on success of info about the existing lock.
   */
  public function patch($id, Request $request) {
    $requestContent = Json::decode($request->getContent());
    $language = \Drupal::languageManager()->getcurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
    $response = new ResourceResponse([FALSE, 'other user']);
    $response->addCacheableDependency(['cache' => ['max-age' => 0]]);

    $identifier = $requestContent['identifier'];
    $node = Node::load($id);
    if ($node->hasTranslation($language)) {
      $node = $node->getTranslation($language);
      $locker = \Drupal::service('pagedesigner.locker')->setEntity($node);
      if ($locker->acquire($identifier)) {
        $response = new ModifiedResourceResponse([TRUE, $identifier]);
      }
      elseif ($locker->hasLock()) {
        $response = new ResourceResponse([FALSE, 'different identifier']);
      }
    }

    return $response;
  }

  /**
   * Delete a lock.
   *
   * Delete the lock on the node.
   *
   * @param int $id
   *   The node id.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   *
   * @return \Drupal\rest\ModifiedResourceResponse
   *   An empty response.
   */
  public function delete($id, Request $request) {
    $requestContent = Json::decode($request->getContent());
    $language = \Drupal::languageManager()->getcurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
    $response = new ResourceResponse(NULL, 404);
    $response->addCacheableDependency(['cache' => ['max-age' => 0]]);

    $node = Node::load($id);
    $identifier = $requestContent['identifier'];
    if ($node->hasTranslation($language)) {
      $node = $node->getTranslation($language);
      $locker = \Drupal::service('pagedesigner.locker');
      $locker->setEntity($node);
      if ($locker->release($identifier)) {
        $response = new ModifiedResourceResponse(NULL, 204);
      }
    }

    return $response;
  }

}
