module SMARTAppLaunch::AuthenticationVerification

def check_authentication(authentication_apporach, request, request_params, jti_list, request_num)

def check_authentication(authentication_apporach, request, request_params, jti_list, request_num)
  case authentication_apporach
  when CONFIDENTIAL_ASYMMETRIC_TAG
    check_client_assertion(request_params['client_assertion'], jti_list, request_num)
  when CONFIDENTIAL_SYMMETRIC_TAG
    check_authorization_header(request, request_num)
  end
end

def check_authorization_header(request, request_num)

def check_authorization_header(request, request_num)
  authorization_header_value = request.request_header('authorization')&.value
  error = MockSMARTServer.confidential_symmetric_header_value_error(authorization_header_value, client_id,
                                                                    smart_client_secret)
  if error.present?
    add_message('error', "Token request #{request_num} invalid: #{e}")
  end
end

def check_client_assertion(assertion, jti_list, request_num)

def check_client_assertion(assertion, jti_list, request_num)
  decoded_token =
    begin
      JWT::EncodedToken.new(assertion)
    rescue StandardError => e
      add_message('error', "Token request #{request_num} contained an invalid client assertion jwt: #{e}")
      nil
    end
  return unless decoded_token.present?
  check_jwt_header(decoded_token.header, request_num)
  check_jwt_payload(decoded_token.payload, jti_list, request_num)
  check_jwt_signature(decoded_token, request_num)
end

def check_jwt_header(header, request_num)

def check_jwt_header(header, request_num)
  return unless header['typ'] != 'JWT'
  add_message('error', "client assertion jwt on token request #{request_num} has an incorrect `typ` header: " \
                       "expected 'JWT', got '#{header['typ']}'")
end

def check_jwt_payload(claims, jti_list, request_num)

def check_jwt_payload(claims, jti_list, request_num)
  if claims['iss'] != client_id
    add_message('error', "client assertion jwt on token request #{request_num} has an incorrect `iss` claim: " \
                         "expected '#{client_id}', got '#{claims['iss']}'")
  end
  if claims['sub'] != client_id
    add_message('error', "client assertion jwt on token request #{request_num} has an incorrect `sub` claim: " \
                         "expected '#{client_id}', got '#{claims['sub']}'")
  end
  if claims['aud'] != client_token_url
    add_message('error', "client assertion jwt on token request #{request_num} has an incorrect `aud` claim: " \
                         "expected '#{client_token_url}', got '#{claims['aud']}'")
  end
  if claims['exp'].blank?
    add_message('error', "client assertion jwt on token request #{request_num} is missing the `exp` claim.")
  end
  if claims['jti'].blank?
    add_message('error', "client assertion jwt on token request #{request_num} is missing the `jti` claim.")
  elsif jti_list.include?(claims['jti'])
    add_message('error', "client assertion jwt on token request #{request_num} has a `jti` claim that was " \
                         "previouly used: '#{claims['jti']}'.")
  else
    jti_list << claims['jti']
  end
end

def check_jwt_signature(encoded_token, request_num)

def check_jwt_signature(encoded_token, request_num)
  error = MockSMARTServer.smart_assertion_signature_verification(encoded_token, smart_jwk_set)
  return unless error.present?
  add_message('error', "Signature validation failed on token request #{request_num}: #{error}")
end