<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.

namespace Yoast\WP\SEO\MyYoast_Client\Infrastructure\OIDC;

/**
 * Provides the MyYoast issuer URL, software statement, and initial access token.
 *
 * All values are filterable for development/staging environments.
 *
 * The `SOFTWARE_STATEMENT` and `INITIAL_ACCESS_TOKEN` constants below may
 * appear committed with real, valid values. This is intentional and safe — both
 * values are public by design, not leaked secrets. The full rationale lives in
 * the doc block at the top of `config/grunt/custom-tasks/update-myyoast-credentials.js`.
 *
 * ┌─────────────────────────────────────────────────────────────────────┐
 * │  *** PLEASE DO NOT FILE A SECURITY REPORT ON THE SOLE GROUNDS   *** │
 * │  *** THAT THESE CREDENTIALS ARE PUBLICLY ACCESSIBLE.            *** │
 * └─────────────────────────────────────────────────────────────────────┘
 *
 * That is by design and the linked doc block explains why. If, having read
 * that rationale, you still believe something here is wrong, please do file
 * a security report through the project's normal disclosure channel;
 * reports about anything else are always welcome.
 */
class Issuer_Config {

	/**
	 * The default production issuer URL.
	 *
	 * @var string
	 */
	private const DEFAULT_ISSUER_URL = 'https://my.yoast.com';

	/**
	 * Software statement JWT for Dynamic Client Registration.
	 *
	 * Populated by the `update-myyoast-credentials` Grunt task as part of the
	 * `artifact` alias on every build. The task fetches a fresh, version-bound
	 * software statement from MyYoast when a service-account token is available
	 * and falls back to a public version-zero software statement otherwise.
	 *
	 * The value committed in source may reflect the most recently shipped
	 * release or be empty on dev branches; this is intentional. At runtime,
	 * non-production environments override this via the
	 * `wpseo_myyoast_software_statement` filter (see `get_software_statement()`).
	 *
	 * Public-by-design — see the class doc block above.
	 *
	 * @var string
	 */
	private const SOFTWARE_STATEMENT = 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6IjMwNTI3ZTlhLWZhMWYtNDhkZS05ZjIzLWUyZGE5MzY0NDE3NiJ9.eyJzb2Z0d2FyZV9pZCI6InlvYXN0L3dvcmRwcmVzcy1zZW8iLCJjbGllbnRfbmFtZSI6IllvYXN0IFNFTyIsImxvZ29fdXJpIjoiaHR0cHM6Ly95b2FzdC5jb20vYXBwL3VwbG9hZHMvMjAyNS8wOS9mcmVlX2ljb24uc3ZnIiwiY2xpZW50X3VyaSI6Imh0dHBzOi8veW9hc3QuY29tL3Byb2R1Y3QveW9hc3Qtc2VvLXdvcmRwcmVzcy8iLCJ0b3NfdXJpIjoiaHR0cHM6Ly95b2FzdC5jb20vdGVybXMtb2Ytc2VydmljZS8iLCJwb2xpY3lfdXJpIjoiaHR0cHM6Ly95b2FzdC5jb20vcHJpdmFjeS1wb2xpY3kvIiwiY29udGFjdHMiOlsic3VwcG9ydEB5b2FzdC5jb20iXSwic29mdHdhcmVfdmVyc2lvbiI6IjI4LjUiLCJjbGVhbnVwX3doZW5faW5hY3RpdmUiOnRydWUsInRva2VuX2VuZHBvaW50X2F1dGhfbWV0aG9kIjoicHJpdmF0ZV9rZXlfand0IiwiaXNzIjoiaHR0cHM6Ly9teS55b2FzdC5jb20iLCJhdWQiOiJodHRwczovL215LnlvYXN0LmNvbSIsImp0aSI6IjJiNzZmNTc3LTFlN2QtNGRlYS1hMDNhLTgxNTk5ODc1MWI5ZCIsImlhdCI6MTc4OTQ1NDM1Mn0.0QRZLt1-lIcJhviULlL1BC_RCJYp1tOY9Yvjw6_QR8OBGp7U1InV21zxrLiEIlsvqSXYa7acyParsXNFtE8ZDg';

	/**
	 * Initial access token for Dynamic Client Registration.
	 *
	 * Populated by the `update-myyoast-credentials` Grunt task as part of the
	 * `artifact` alias on every build. The task fetches a fresh, initial access
	 * token from MyYoast when a service-account token is available and falls
	 * back to a public version-zero token otherwise.
	 *
	 * The value committed in source may reflect the most recently shipped
	 * release or be empty or v0 on dev branches; this is intentional. At
	 * runtime, non-production environments override this via the
	 * `wpseo_myyoast_initial_access_token` filter (see
	 * `get_initial_access_token()`).
	 *
	 * Public-by-design — see the class doc block above.
	 *
	 * @var string
	 */
	private const INITIAL_ACCESS_TOKEN = 'otDqV0NtvCxH9C1xYTBW4Tzf4spAStdpf59eIJ7PA6F';

	/**
	 * Returns the MyYoast issuer URL.
	 *
	 * @return string The issuer URL (without trailing slash).
	 */
	public function get_issuer_url(): string {
		/**
		 * Filters the MyYoast issuer URL.
		 *
		 * @internal
		 *
		 * @param string $issuer_url The issuer URL.
		 */
		return \rtrim( \apply_filters( 'wpseo_myyoast_issuer_url', self::DEFAULT_ISSUER_URL ), '/' );
	}

	/**
	 * Returns the software statement JWT.
	 *
	 * @return string The signed software statement JWT.
	 */
	public function get_software_statement(): string {
		/**
		 * Filters the MyYoast software statement JWT.
		 *
		 * @internal
		 *
		 * @param string $software_statement The software statement JWT.
		 */
		return \apply_filters( 'wpseo_myyoast_software_statement', self::SOFTWARE_STATEMENT );
	}

	/**
	 * Returns the initial access token for Dynamic Client Registration.
	 *
	 * @return string The initial access token.
	 */
	public function get_initial_access_token(): string {
		/**
		 * Filters the MyYoast initial access token.
		 *
		 * @internal
		 *
		 * @param string $initial_access_token The initial access token.
		 */
		return \apply_filters( 'wpseo_myyoast_initial_access_token', self::INITIAL_ACCESS_TOKEN );
	}

	/**
	 * Returns a short hash suffix derived from the issuer URL.
	 *
	 * Used to scope storage keys (options, transients, user meta) to the
	 * current issuer, so that switching issuers isolates all stored data.
	 *
	 * @return string An 8-character hex string.
	 */
	public function get_issuer_key(): string {
		return \substr( \md5( $this->get_issuer_url() ), 0, 8 );
	}

	/**
	 * Returns the OIDC discovery document URL.
	 *
	 * @return string The discovery URL.
	 */
	public function get_discovery_url(): string {
		return $this->get_issuer_url() . '/.well-known/openid-configuration';
	}
}
