<?php
     header("Access-Control-Allow-Origin: http://localhost/rest-api-authentication-example/");
    //header("Content-Type: application/json; charset=UTF-8");
    header("Access-Control-Allow-Methods: POST");
    header("Access-Control-Max-Age: 3600");
    header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
     
    // files needed to connect to database
    
     $pathRoot = $_SERVER['DOCUMENT_ROOT'];
    include_once  $pathRoot ."/saia/api/v1/config/database.php";
    include_once $pathRoot ."/saia/api/v1/objects/adminUser.php";
    
    include_once $pathRoot ."/saia/api/v1/objects/token.php";
    include_once $pathRoot ."/saia/api/v1/ps_office/token_data.php";
    
    //========== Files needed for email =====================================
    include_once $pathRoot ."/saia/api/v1/sendmail/customMailSender.php";
    
    
    //================= JWT Library ==========================================
         include_once $pathRoot ."/saia/api/v1/config/core.php";
         include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/BeforeValidException.php";
         include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/ExpiredException.php";
         include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/SignatureInvalidException.php";
         include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/JWT.php";
          use \Firebase\JWT\JWT;
    
       $jwtDta = "";
       $jwtUserId = 0;
       $jwtUserEmail = "";
    //========================================================================
     
    // get database connection
    $database = new Database();
    $db = $database->getConnection();
    
    //==== Get JSON data ===========
    //$data = json_decode(file_get_contents("php://input"));
    $data = json_decode(file_get_contents("php://input"));
	try{
		$action = $data->action;
	}catch(Exception $e){
		$action = "";
    }
	
   // $action = $data->action;
     $emptyData= "";
	if(is_null($action)){
		$action = "";
	}
    if(strcmp($action, $emptyData) == 0){
        http_response_code(400);
         echo json_encode(array("responseCode"=>400,"results"=>"no valid action"));
        return ;
    }
    
    //================== LOGIN ================================================
    if(strcmp($action, "Login") == 0)
    {
         $email = $data->email;
		if(is_null($email)){
			$email = "";
		}
         if(strcmp($email, $emptyData)==0){
             http_response_code(400);
            echo json_encode(array("responseCode"=>400,"results"=>"no valid data"));
            return ; 
         }
        $adminUser = new AdminUser($db);
        $email_exists = $adminUser->emailExists($email);
        if($email_exists && password_verify($data->password, $adminUser->password))
        {
         
            $token = array(
               "iss" => $iss,
               "aud" => $aud,
               "iat" => $iat,
               "nbf" => $nbf,
               "data" => array(
                   "id" => $adminUser->id,
                   "firstname" => $adminUser->name,
                   "surname" => $adminUser->surname,
                   "email" => $adminUser->email
               )
            );
         
            // set response code
            http_response_code(200);
         
            // generate jwt
            $jwt = JWT::encode($token, $key);
            echo json_encode(
                    array(
                        "responseCode" => 200,
                        "results" => "ok" ,
                        "token" => $jwt
                    )
                );
         
        }else
        {
         
            // set response code
            http_response_code(401);
         
            // tell the user login failed
            //echo json_encode(array("message" => "Login failed."));
            echo json_encode(array( "responseCode" => 401,
                        "results" => "fail"));
        }
        
        return;
    }
    
    //======================== Insert User ====================================
      if(strcmp($action, "Insert") == 0)
    {

        $email = $data->email;
		if(is_null($email)){
			$email = "";
		}
         if(strcmp($email, $emptyData)==0){
             http_response_code(400);
            echo json_encode(array("responseCode"=>400,"results"=>"no valid data"));
            return ; 
         }
         try{
             $adminUser = new AdminUser($db);

            $adminUser->email = $email;
			if(is_null($data->name)){
				http_response_code(400);
				echo json_encode(array("responseCode"=>400,"results"=>"data missing"));
				return ; 
			}
             $adminUser->name = $data->name;
			if(is_null($data->surname)){
				http_response_code(400);
				echo json_encode(array("responseCode"=>400,"results"=>"data missing"));
				return ; 
			}
             $adminUser->surname = $data->surname;
			 if(is_null($data->password)){
				http_response_code(400);
				echo json_encode(array("responseCode"=>400,"results"=>"data missing"));
				return ; 
			}
            $adminUser->password = $data->password;

            $saveResults = $adminUser->insertUser();
            if(strcmp($saveResults,"true")==0)
            {
                 http_response_code(200);
                 echo json_encode(array("responseCode"=>200,"results"=>"saved".$adminUser->feedback));
                 return;
            }
            
             echo json_encode(array("responseCode"=>500,"results"=>"error:".$adminUser->feedback));
             return;
         }catch(Exception $e){
              
             http_response_code(401);
            echo json_encode(array("responseCode"=>401,"results"=>"error:".$e));
            return;
         }
 
    }
    
    //========================= Create Tokens ==================================
     if(strcmp($action, "CreateTokens") == 0)
    {
        
        //----------------- Get JWT from Header ----------------------
        try{
            $jwtAuth =  getBearerToken();
            $jwt=isset($jwtAuth) ? $jwtAuth : "";
            if(strcmp($jwt, "") == 0){
                 http_response_code(401);
                 echo json_encode(array("responseCode"=>401));
                return;
            }
        }catch (Exception $e){
             http_response_code(401);
             echo json_encode(array("responseCode"=>401));
             return;
    
        }
        
        if(strcmp($jwt, "") != 0){
    

            try {
            // decode jwt
                $decoded = JWT::decode($jwt, $key, array('HS256'));
                
    
            // show user details
               $jwtDta = $decoded->data;
               $jwtUserId = $jwtDta -> id;
               $jwtUserEmail = $jwtDta -> email;
    
               $adminUser = new AdminUser($db);

               $adminUser->email = $jwtUserEmail;
               $adminUser->id =  $jwtUserId;
               $callResponse = array();           
    
               if($adminUser->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){
                   http_response_code(200);
                    $tokenCount = $data->tokenCount;
                    $allocation = $data->allocation;
                    $tokenType = $data->tokenType;
                    $callResponse["responseCode"] = "200";
                    if($tokenCount==0){
                        http_response_code(500);
                        $callResponse["responseCode"] = "500";
                        $callResponse["results"] = "No valid counter";
                        echo json_encode($callResponse);
                        return;
                         
                    }
                    //  $date = new DateTime('now', new DateTimeZone('Africa/Johannesburg'));
                    //   $date->format('Y-m-d H:i:s');
                    date_default_timezone_set('Africa/Johannesburg');
                    $date = date('Y-m-d H:i:s');

                   $tokenClass = new Token($db);
                   try{
                       $arrayToken = $tokenClass->generateNewTokens($tokenCount,$jwtUserEmail,$allocation,$tokenType,$date);
                   }catch(Exception $e){
                       http_response_code(500);
                       $callResponse["responseCode"] = "500";
                        $callResponse["results"] = $e;
                          echo json_encode($callResponse);
                          return;
                   }
                   http_response_code(200);
                   $response["responseCode"] = "200";
                   $callResponse["results"] = "Success";
                   $callResponse["dateCreated"] = $date;
                   $callResponse["tokenList"] = $arrayToken;
                   echo json_encode($callResponse);
                   return;
               }
               http_response_code(401);
               $response["responseCode"] = "401";
                $response["results"] = "No valid user";
               echo json_encode($response);
              return;
    
    
             }catch (Exception $e){
                http_response_code(500);
                $callResponse["responseCode"] = "500";
                $callResponse["results"] = $e;
                echo json_encode($callResponse);
                return;
                 
            }
        }
        
        
    }
      //========================= Get Generated Tokens  =======================
      //======================================================================
     if(strcmp($action, "GetGeneratedTokens") == 0)
    {
        $createdBy = $data->createdBy;      
        $adminUser = new AdminUser($db);
		$jwtAuth = verifyJWT($db,$key,$adminUser);
		if(strcmp($jwtAuth,"unauthorized")==0){
			http_response_code(401);
            echo json_encode(array("responseCode"=>401));
            return;
			
		}


		$tokenData = new TokenData($db);
		$listGeneratedTokens = $tokenData->getGenratedTokenList($createdBy);
		echo $listGeneratedTokens;
		return;
    }
    
    //=========================================================================
    echo json_encode(array("responseCode"=>400,"results"=>"no valid action"));
    
//=============================================================================
function verifyJWT($db,$key,$adminUser){
		  //----------------- Get JWT from Header ----------------------
		   $emptyString = "";
        try{
            $jwtAuth =  getBearerToken();
            $jwt=isset($jwtAuth) ? $jwtAuth : "";
           
            if(strcmp($jwt, $emptyString) == 0){
                
                return "unauthorized";
            }
        }catch (Exception $e){
             return "unauthorized";
    
        }

        if(strcmp($jwt, $emptyString) != 0){
    

            try {
            // decode jwt
            $decoded = JWT::decode($jwt, $key, array('HS256'));
            // show user details
               $jwtDta = $decoded->data;
               $jwtUserId = $jwtDta -> id;
               $jwtUserEmail = $jwtDta -> email;
    
               //$adminUser = new AdminUser($db);

               $adminUser->email =$jwtUserEmail;
               $adminUser->id =  $jwtUserId;
               $callResponse = array();      
               //echo $jwtUserEmail . " ". $jwtUserId;
    
               if($adminUser->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){
                   
                   return "authorized";
               }
              
               return "unauthorized";
    
    
             }catch (Exception $e){
                return "unauthorized";
                 
            }
        }
		
	}

    
/** 
 * Get header Authorization
 * */
 
function getAuthorizationHeader(){
        $headers = null;
        if (isset($_SERVER['Authorization'])) {
            $headers = trim($_SERVER["Authorization"]);
        }
        else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
            $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
        } elseif (function_exists('apache_request_headers')) {
            $requestHeaders = apache_request_headers();
            // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
            $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
            //print_r($requestHeaders);
            if (isset($requestHeaders['Authorization'])) {
                $headers = trim($requestHeaders['Authorization']);
            }
        }
       // $headers = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDAsImRhdGEiOnsiaWQiOiIzIiwiZW1haWwiOiJlbWlsZUBpZGVhczRhcHBzLmNvLnphIn19.PsusjAZ10bdOtOuB0CCTv9O3D68-v_YRaCC48oYh_EI";
        return $headers;
    }
/**
 * get access token from header
 * */
function getBearerToken() {
    $headers = getAuthorizationHeader();
    // HEADER: Get the access token from the header
    if (!empty($headers)) {
        if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
            return $matches[1];
        }
    }
    return "";
}
