<?php

/**
 * This program is written and copyrighted by Franz Geffke (Softmax Co., Ltd.)
 */

namespace ones\oidc;

use Exception;

/**
 * Get OpenID configuration
 * 
 * @param string $host The host of the OpenID provider
 * @return array{
 *     authorization_endpoint: string,
 *     claims_parameter_supported: bool,
 *     claims_supported: string[],
 *     code_challenge_methods_supported: string[],
 *     end_session_endpoint: string,
 *     grant_types_supported: string[],
 *     issuer: string,
 *     jwks_uri: string,
 *     registration_endpoint: string,
 *     authorization_response_iss_parameter_supported: bool,
 *     response_modes_supported: string[],
 *     response_types_supported: string[],
 *     scopes_supported: string[],
 *     subject_types_supported: string[],
 *     token_endpoint_auth_methods_supported: string[],
 *     token_endpoint_auth_signing_alg_values_supported: string[],
 *     token_endpoint: string,
 *     id_token_signing_alg_values_supported: string[],
 *     id_token_encryption_alg_values_supported: string[],
 *     id_token_encryption_enc_values_supported: string[],
 *     pushed_authorization_request_endpoint: string,
 *     request_parameter_supported: bool,
 *     request_uri_parameter_supported: bool,
 *     request_object_signing_alg_values_supported: string[],
 *     require_request_uri_registration: bool,
 *     require_signed_request_object: bool,
 *     request_object_encryption_alg_values_supported: string[],
 *     request_object_encryption_enc_values_supported: string[],
 *     userinfo_endpoint: string,
 *     introspection_endpoint: string,
 *     revocation_endpoint: string,
 *     backchannel_authentication_endpoint: string,
 *     backchannel_token_delivery_modes_supported: string[],
 *     backchannel_user_code_parameter_supported: bool,
 *     backchannel_authentication_request_signing_alg_values_supported: string[],
 *     claim_types_supported: string[]
 * }
 */
function fetch_openid_config($host) {
    $url = $host . '/oidc/.well-known/openid-configuration';
    $response = file_get_contents($url);
    $decoded_response = json_decode($response, true);

    // Validate the decoded response
    if (isset($decoded_response['issuer'])) {
        return $decoded_response;
    } else {
        // Handle the error case where 'issuer' is not set
        throw new Exception('Invalid OpenID configuration: issuer not found on: ' . $url);
    }
}

/**
 * Get OpenID provider metadata
 * 
 * @param string $providerMetadata The OpenID provider metadata
 */
function fetch_openid_provider_jwks($providerMetadata) {
    $response = file_get_contents($providerMetadata['jwks_uri']);
    $decoded_response = json_decode($response, true);

    // Validate the decoded response
    if (isset($decoded_response['keys'])) {
        return $decoded_response;
    } else {
        // Handle the error case where 'keys' is not set
        throw new Exception('Invalid OpenID provider JWKS: keys not found on: ' . $providerMetadata['jwks_uri']);
    }
}

/**
 * Get OpenID info
 */
function get_openid_info($host) {
    $providerMetadata = null;
    try {
        $providerMetadata = fetch_openid_config($host);
    } catch (Exception $e) {
        throw new Exception("Error getting OpenID configuration: " . $e->getMessage());
    }

    // Get OpenID provider JWKS
    $providerJwks = null;
    try {
        $providerJwks = fetch_openid_provider_jwks($providerMetadata);
    } catch (Exception $e) {
        throw new Exception("Error getting OpenID provider JWKS: " . $e->getMessage());
    }

    echo "OpenID provider JWKS: " . json_encode($providerJwks) . "\n";

    return [
        'providerMetadata' => $providerMetadata,
        'providerJwks' => $providerJwks
    ];
}

?>