<?php
error_reporting(0);
class AzureController {
	public $db_handle, $client_id, $client_secret, $redirect_url, $auth_url, $token_url, $graph_api_url, $access_token, $refresh_token;
	
	
	public function __construct(){
		$this->db_handle = new DBController();
		$this->client_id = $this->getMetaValue('client_id');
		$this->client_secret = $this->getMetaValue('client_secret');
		$this->redirect_url = $this->getMetaValue('redirect_url');
		$this->auth_url = $this->getMetaValue('auth_url');
		$this->token_url = $this->getMetaValue('token_url');
		$this->graph_api_url = $this->getMetaValue('graph_api_url');
		$this->access_token = $this->getMetaValue('access_token');
		$this->refresh_token = $this->getMetaValue('refresh_token');
	}
	
	public function refreshAccessToken(){
		if($this->refresh_token){
			$payload = [
		        'client_id' => $this->client_id,
		        'client_secret' => $this->client_secret,
		        'refresh_token' => $this->refresh_token,
		        'grant_type' => 'refresh_token'
		    ];
		    
		    $response = $this->sendRequest($this->token_url, $payload);
		    
		    if(!empty($response['access_token'])){
		    	$this->updateMeta('access_token', $response['access_token']);
		    	$this->updateMeta('refresh_token', $response['refresh_token']);
		    	
		    	$this->refresh_token = $response['refresh_token'];
		    	$this->access_token = $response['access_token'];
		    }
		}
		
		return false;
	}
	
	public function sendRequest($url, $payload) {
		$headers = ['Content-Type: application/x-www-form-urlencoded'];
		
		$ch = curl_init($url);
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($ch, CURLOPT_POST, true);
	    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
	    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	
	    $response = curl_exec($ch);
	    curl_close($ch);
	
	    return json_decode($response, true);
	}
	
	public function uploadFileToOneDrive($full_path, $file_path) {
		$this->refreshAccessToken();
		
	    $ch = curl_init($full_path);
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($ch, CURLOPT_PUT, true);
	    curl_setopt($ch, CURLOPT_INFILE, fopen($file_path, 'r'));
	    curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file_path));
	    curl_setopt($ch, CURLOPT_HTTPHEADER, [
	        'Authorization: Bearer ' . $this->access_token,
	        'Content-Type: application/octet-stream'
	    ]);
	
	    $response = curl_exec($ch);
	    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	    curl_close($ch);
	    
	    $response = json_decode($response, true);
	    
	    if ($httpCode == 201 || $httpCode == 200) {
	        // Return the OneDrive ID of the uploaded file
	        return ['id' => $response['id']];
	    } else {
	    	return ['error' => "Failed to upload file to OneDrive: " . $response['error']['message']];
	    }
	}
	
	public function getDownloadUrl($onedrive_id){
		if($onedrive_id){
			$this->refreshAccessToken();
			
			$url = "https://graph.microsoft.com/v1.0/me/drive/items/".$onedrive_id."?select=id,@microsoft.graph.downloadUrl";
			
			$ch = curl_init($url);
		    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		    curl_setopt($ch, CURLOPT_HTTPHEADER, [
		        'Authorization: Bearer ' . $this->access_token,
		    ]);
		
		    $response = curl_exec($ch);
		    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
		    curl_close($ch);
		    $response = json_decode($response, true);
		    	
		    return !empty($response['@microsoft.graph.downloadUrl']) ? $response['@microsoft.graph.downloadUrl'] : '';
		}
		else{
			return '';
		}
	}
	
	public function createShareableLink($onedrive_id) {
	    $url = "https://graph.microsoft.com/v1.0/me/drive/items/$onedrive_id/createLink";
	    
	    $data = json_encode([
	        "type" => "view",
	        "scope" => "anonymous"
	    ]);
	
	    $ch = curl_init($url);
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($ch, CURLOPT_POST, true);
	    curl_setopt($ch, CURLOPT_HTTPHEADER, [
	        'Authorization: Bearer ' . $this->access_token,
	        'Content-Type: application/json',
	    ]);
	    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	
	    $response = curl_exec($ch);
	    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	    $error = curl_error($ch);
	    curl_close($ch);
	
	    $response = json_decode($response, true);
		
		return !empty($response['link']['webUrl']) ? $response['link']['webUrl'] : '';
	}
	
	public function deleteFileFromOneDrive($onedrive_id) {
	    $url = "https://graph.microsoft.com/v1.0/me/drive/items/$onedrive_id";
	    $ch = curl_init($url);
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
	    curl_setopt($ch, CURLOPT_HTTPHEADER, [
	        'Authorization: Bearer ' . $this->access_token,
	    ]);
	
	    $response = curl_exec($ch);
	    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	    curl_close($ch);
	
	    return $httpCode == 204; // HTTP 204 No Content indicates success
	}
	
	public function getMetaData($name){
		$sql = "SELECT * FROM azure_meta WHERE meta_name = '".$name."'";
		$result = $this->db_handle->runQuery($sql);
		
		$meta_data = [];
		if(!empty($result[0])){
			$result = $result[0];
			$result['meta_value'] = ($result['is_serialized'] == 1) ? json_decode($result['meta_value'], true) : $result['meta_value'];
			
			$meta_data = $result;
		}
		
		return $meta_data;
	}
	
	public function getMetaValue($name){
		$meta = $this->getMetaData($name);
		return !empty($meta) ? $meta['meta_value'] : '';
	}
	
	public function updateMeta($name, $value, $is_serialized = 0){
		// check if meta already exists
		$meta = $this->getMetaData($name);
		$value = $is_serialized ? json_encode($value) : $value;
		
		if(!empty($meta)){
			$sql = "UPDATE azure_meta SET meta_value = '".$value."', is_serialized = '".$is_serialized."' WHERE id = '".$meta['id']."'";
		}
		else{
			$sql = "INSERT azure_meta SET name = '".$name."', meta_value = '".$value."', is_serialized = '".$is_serialized."'";
		}
		
		return $this->db_handle->executeQuery($sql);
	}
}