<?php

namespace Drupal\oauth_server_sso;
use Symfony\Component\HttpFoundation\Response;


class handler{

  static function generateRandom($length=30){
    $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $charactersLength = strlen($characters);
    $randomString = '';
      for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
      }
    return $randomString;
  }

  static function validateAuthCode($request_time,$user_id){
    $current_time = time();
    if($current_time - $request_time >=90){
      \Drupal::logger('oauth_server_sso')->error("auth code issued at : $request_time");
      \Drupal::logger('oauth_server_sso')->error("current epoch unix timestamp : $current_time");
      return self ::returnSymfonyResponseObject(json_encode(array("statusCode" => "InvalidAuthCode","statusMessage" => "Bad request, the authorization code is expired")),Response::HTTP_BAD_REQUEST);
    }
     DBQueries ::insert_code_from_user_id('', $user_id);
  }

  static function validateAccessToken($request_time){
    $current_time = time();
    if($current_time - $request_time >=3600){
      \Drupal::logger('oauth_server_sso')->error("access toekn issued at : $request_time");
      \Drupal::logger('oauth_server_sso')->error("current epoch unix timestamp : $current_time");
      return self::returnSymfonyResponseObject(json_encode(array("statusCode" => "InvalidAuthenticationToken","statusMessage" => "Lifetime validation failed, the token is expired.")),Response::HTTP_UNAUTHORIZED);
    }
  }

  static function oauth_server_sso_validate_clientSecret($client_secret){
    $secret_stored = \Drupal::config('oauth_server_sso.settings')->get('oauth_server_sso_client_secret');
    if($client_secret != $secret_stored){
      \Drupal::logger('oauth_server_sso')->error("client_secret in current request : $client_secret");
      \Drupal::logger('oauth_server_sso')->error("client_secret stored at OAuth server : $secret_stored");
      return self ::returnSymfonyResponseObject(json_encode(array("statusCode" => "UnauthorizedClient","statusMessage" => 'Invalid client secret provided. Ensure the client secret being sent in the request is the correct, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.')),Response::HTTP_UNAUTHORIZED);
    }
  }

  static function oauth_server_sso_validate_grant($grant_type){
    if($grant_type != "authorization_code"){
      \Drupal::logger('oauth_server_sso')->error("grant_type in current request : $grant_type");
      return self ::returnSymfonyResponseObject(json_encode(array("statusCode" => "InvalidGrantType","statusMessage" => 'Only the Authorization Code grant type (authorization_code) is supported in the free version of the module. If you want to use any other grant type, you can reach out to us at <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to upgrade to the premium version of the module.')),Response::HTTP_BAD_REQUEST);
    }
  }

  static function oauth_server_sso_validate_clientId($client_id, $auth_ep=false){
    $id_stored = \Drupal::config('oauth_server_sso.settings')->get('oauth_server_sso_client_id');
    if($client_id != $id_stored){
      $error_message='Client ID is mismatched';
      $solution='head over to OAuth Client tab of the Drupal OAuth Server module. Copy the value of Client ID from there and paste it in the Client ID field of OAuth Client, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.';
      \Drupal::logger('oauth_server_sso')->error("client_id in current request : $client_id");
      \Drupal::logger('oauth_server_sso')->error("client_id stored at OAuth server : $id_stored");
      if($auth_ep)
        self::show_error_message($error_message,$solution);
      else
        return self ::returnSymfonyResponseObject(json_encode(array("statusCode" => "UnauthorizedClient","statusMessage" => 'The Client was not found in the directory. Ensure the Client ID being sent in the request is the correct, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.')),Response::HTTP_BAD_REQUEST);
    }
  }

  static function oauth_server_sso_validate_redirectUrl($redirect_uri, $auth_ep = false){
    $redirect_url_stored = \Drupal::config('oauth_server_sso.settings')->get('oauth_server_sso_redirect_url');
    if(empty($redirect_uri) || empty($redirect_url_stored) || $redirect_uri != $redirect_url_stored){
      \Drupal::logger('oauth_server_sso')->error("redirect_uri in current request : $redirect_uri");
      \Drupal::logger('oauth_server_sso')->error("redirect_uri stored at OAuth server : $redirect_url_stored");
      $error_message='Redirect URL is mismatched';
      $solution='head over to OAuth Client tab of the Drupal OAuth Server module. Enter the client Redirect URL in Redirect/Callback URL field, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.';
      if($auth_ep)
        self::show_error_message($error_message,$solution);
      else
        return self ::returnSymfonyResponseObject(json_encode(array("statusCode" => "InvalidRedirectURL","statusMessage" => 'Invalid Redirect URL provided. Ensure the Redirect URL being sent in the request is the correct, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.')),Response::HTTP_BAD_REQUEST);
    }
  }

  static function oauth_server_sso_validate_scope($scope,$user){
    if($scope!=''){
      $scope_values = explode(" ", $scope);
      $scope_exists = FALSE;
      foreach ($scope_values as $scope1){
        if($scope1 == "profile" || $scope1 == "openid" || $scope1 == "email"){
          $scope_exists = TRUE;
          break;
        }
      }
      if($scope_exists === FALSE){
        $error_message='Scope is mismatched';
        $solution='head over to OAuth Client tab of the Drupal OAuth Server module. Copy the value of Scope from there and paste it in the Scope field of OAuth Client, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.';
        self::show_error_message($error_message,$solution);
      }else{
        DBQueries ::insertScopeInTable($scope,$user);
      }
    }else{
        $error_message='Scope is not configured';
        $solution='head over to OAuth Client tab of the Drupal OAuth Server module. Copy the value of Scope from there and paste it in the Scope field of OAuth Client, also you can reach out to us on <a href = "mailto: drupalsupport@xecurify.com">drupalsupport@xecurify.com</a> to resolve the issue.';
        self::show_error_message($error_message,$solution);
    }
  }

  static function show_error_message($error_message,$solution){
    echo '<div style="font-family:Calibri;padding:0 3%;">';
    echo '<div style="color: #a94442;background-color: #f2dede;padding: 15px;margin-bottom: 20px;text-align:center;border:1px solid #E6B3B2;font-size:18pt;"> ERROR</div>
                        <div style="color: #a94442;font-size:14pt; margin-bottom:20px;"><p><strong>Error: </strong>' .$error_message.'.</p>
                            <p>'.$solution.'</p></div>';
    exit;
  }

  Public static function returnSymfonyResponseObject($json_encoded_response, $status_code){
    if($status_code==Response::HTTP_OK)
     \Drupal::logger('oauth_server_sso')->info("response sent => $json_encoded_response");
    else
     \Drupal::logger('oauth_server_sso')->error("response sent => $json_encoded_response");

    $response = new Response($json_encoded_response);
    $response->headers->set('Content-Type', 'application/json');
    $response->headers->set('Access-Control-Allow-Origin', '*');
    $response->setStatusCode($status_code);
    $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    return $response;
  }

}
