<?php


namespace Fliegerlogin\VereinsfliegerApi\Api;

// phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Der Sniff haelt jede Interpolation fuer Ausgabe. Hier entsteht keine: die Werte gehen in Exception-Objekte, die intern gefangen und erst nach dem Maskieren angezeigt werden.


use Fliegerlogin\VereinsfliegerApi\Exceptions\HttpException;
use Fliegerlogin\VereinsfliegerApi\Exceptions\ApiException;
use Fliegerlogin\VereinsfliegerApi\Model\SignInCredentialsDto;
use Fliegerlogin\VereinsfliegerApi\Responses\AccessTokenResponse;
use Fliegerlogin\VereinsfliegerApi\Responses\LoginFailedResponse;
use Fliegerlogin\VereinsfliegerApi\Responses\OkResponse;
use Fliegerlogin\VereinsfliegerApi\Responses\UnauthorizedResponse;
use Fliegerlogin\VereinsfliegerApi\Responses\UserResponse;
use GuzzleHttp\Exception\GuzzleException;

class AuthApi extends AbstractApi {

	/**
	 * @return AccessTokenResponse
	 * @throws HttpException
	 * @throws ApiException
	 */
	public function getAccesstoken(): AccessTokenResponse {
		try {
			$response = $this->client->request('GET', "{$this->baseUrl}/auth/accesstoken", $this->getHttpOptions([], true));

			switch ($response->getStatusCode()) {
				case 200:
					return $this->deserializeResponse($response, AccessTokenResponse::class);

				default:
					throw new ApiException($response);
			}
		} catch (GuzzleException $e) {
			throw new HttpException($e);
		}
	}

	/**
	 * @param SignInCredentialsDto $credentials
	 * @return OkResponse
	 * @throws HttpException
	 * @throws ApiException
	 */
	public function Signin(SignInCredentialsDto $credentials): OkResponse {
		try {
			$response = $this->client->request('POST', "{$this->baseUrl}/auth/signin", $this->getHttpOptions([
				'form_params' => $this->serializeRequestParams($credentials)
			]));

			switch ($response->getStatusCode()) {
				case 200:
					return $this->deserializeResponse($response, OkResponse::class);

				case 403:
					throw new ApiException(
						$response,
						$this->deserializeResponse($response, LoginFailedResponse::class)
					);

				default:
					throw new ApiException($response);
			}
		} catch (GuzzleException $e) {
			throw new HttpException($e);
		}
	}

	/**
	 * @return OkResponse
	 * @throws HttpException
	 * @throws ApiException
	 */
	public function Signout(): OkResponse {
		try {
			$response = $this->client->request('DELETE', "{$this->baseUrl}/auth/signout", $this->getHttpOptions());

			switch ($response->getStatusCode()) {
				case 200:
					return $this->deserializeResponse($response, OkResponse::class);

				case 401:
					throw new ApiException(
						$response,
						$this->deserializeResponse($response, UnauthorizedResponse::class)
					);

				default:
					throw new ApiException($response);
			}
		} catch (GuzzleException $e) {
			throw new HttpException($e);
		}
	}

	/**
	 * @return UserResponse
	 * @throws ApiException
	 * @throws HttpException
	 */
	public function GetUser(): UserResponse {
		try {
			$response = $this->client->request('POST', "{$this->baseUrl}/auth/getuser", $this->getHttpOptions());

			switch ($response->getStatusCode()) {
				case 200:
					return $this->deserializeResponse($response, UserResponse::class);

				case 401:
					throw new ApiException(
						$response,
						$this->deserializeResponse($response, UnauthorizedResponse::class)
					);

				default:
					throw new ApiException($response);
			}
		} catch (GuzzleException $e) {
			throw new HttpException($e);
		}
	}

}
