<?php

namespace WPLEClient;

use WPLEClient\Exceptions\LEAuthorizationException;

/**
 * LetsEncrypt Authorization class, getting LetsEncrypt authorization data associated with a LetsEncrypt Order instance.
 *
 * PHP version 5.2.0
 *
 * MIT License
 *
 * Copyright (c) 2018 Youri van Weegberg
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * @author     Youri van Weegberg <youri@yourivw.nl>
 * @copyright  2018 Youri van Weegberg
 * @license    https://opensource.org/licenses/mit-license.php  MIT License
 * @link       https://github.com/yourivw/LEClient
 * @since      Class available since Release 1.0.0
 */
class LEAuthorization
{
  private $connector;

  public $authorizationURL;
  public $identifier;
  public $status;
  public $expires;
  public $challenges;

  private $log;

  /**
   * Initiates the LetsEncrypt Authorization class. Child of a LetsEncrypt Order instance.
   *
   * @param LEConnector	$connector			The LetsEncrypt Connector instance to use for HTTP requests.
   * @param int 			$log 				The level of logging. Defaults to no logging. LOG_OFF, LOG_STATUS, LOG_DEBUG accepted.
   * @param string 		$authorizationURL 	The URL of the authorization, given by a LetsEncrypt order request.
   */
  public function __construct($connector, $log, $authorizationURL)
  {
    $this->connector = $connector;
    $this->log = $log;
    $this->authorizationURL = $authorizationURL;

    $sign = $this->connector->signRequestKid('', $this->connector->accountURL, $this->authorizationURL);
    $post = $this->connector->post($this->authorizationURL, $sign);
    if ($post['status'] === 200) {
      $this->identifier = $post['body']['identifier'];
      $this->status = $post['body']['status'];
      $this->expires = $post['body']['expires'];
      $this->challenges = $post['body']['challenges'];
    } else {
      if ($this->log instanceof \Psr\Log\LoggerInterface) {
        $this->log->info('Cannot find authorization \'' . $authorizationURL . '\'.');
      } elseif ($this->log >= LEClient::LOG_STATUS) LEFunctions::log('Cannot find authorization \'' . $authorizationURL . '\'.', 'function LEAuthorization __construct');
    }
  }

  /**
   * Updates the data associated with the current LetsEncrypt Authorization instance.
   */

  public function updateData()
  {
    $sign = $this->connector->signRequestKid('', $this->connector->accountURL, $this->authorizationURL);
    $post = $this->connector->post($this->authorizationURL, $sign);
    if ($post['status'] === 200) {
      $this->identifier = $post['body']['identifier'];
      $this->status = $post['body']['status'];
      $this->expires = $post['body']['expires'];
      $this->challenges = $post['body']['challenges'];
    } else {
      if ($this->log instanceof \Psr\Log\LoggerInterface) {
        $this->log->info('Cannot find authorization \'' . $this->authorizationURL . '\'.');
      } elseif ($this->log >= LEClient::LOG_STATUS) LEFunctions::log('Cannot find authorization \'' . $this->authorizationURL . '\'.', 'function updateData');
    }
  }

  /**
   * Gets the challenge of the given $type for this LetsEncrypt Authorization instance. Throws a Runtime Exception if the given $type is not found in this
   * LetsEncrypt Authorization instance.
   *
   * @param int	$type 	The type of verification. Supporting LEOrder::CHALLENGE_TYPE_HTTP and LEOrder::CHALLENGE_TYPE_DNS.
   *
   * @return array	Returns an array with the challenge of the requested $type.
   */
  public function getChallenge($type)
  {
    foreach ($this->challenges as $challenge) {
      if ($challenge['type'] == $type) return $challenge;
    }
    throw LEAuthorizationException::NoChallengeFoundException($type, $this->identifier['value']);
  }
}
