<?php
	defined('BASEPATH') OR exit('No direct script access allowed');
	class Aws3 extends My_Model {

		public function __construct(){
			parent::__construct();
		}

		public function putObject($filename, $project_name, $aws_result = array()){

			if(!empty($aws_result)){

				$aws_access_key_id = trim($aws_result['access_key_id']);
				$aws_secret_access_key = trim($aws_result['secret_access_key']);

				// Bucket
				$bucket_name = trim($aws_result['bucket_name']);

				$aws_region = trim($aws_result['region_name']);
				$host_name = $bucket_name . '.s3.'.$aws_region.'.amazonaws.com';

				$new_file_name = $this->random_string_create(6).'-'.str_replace(" ", "-", $this->clean($filename['name']));
				$extension = $this->getExtension($new_file_name);

				$a = $this->clean($filename['name']);
				$path_parts = pathinfo($a);
				$a_without_ext = $path_parts['filename'];
				$extension = $this->getExtension($a);

				if($a_without_ext != "" && $extension != ""){
					$new_file_name = $a_without_ext.'_'.$this->random_string_create(4).'.'.$extension;
				}

				

				// Server path where content is present. This is just an example
				$content_path = $filename['tmp_name'];
				$content = file_get_contents($content_path);
				$content_type = $filename['type'];
				$image_type = array('image/jpeg','image/jpg','image/png','image/x-png');


				//thumbnail
	        	$thumbnail[0] = 100;
	        	$thumbnail[1] = 100;

	        	//medium
	        	$medium[0] = 300;
	        	$medium[1] = 300;

	        	//large
	        	$large[0] = 1024;
	        	$large[1] = 1024;


				// MIME type of file. Very important to set if you later plan to load the file from a S3 url in the browser (images, for example)

	        	if(ob_get_level()) ob_end_clean();
        		$content_path = $filename['tmp_name'];
				$content = file_get_contents($content_path);
				$content_length = $filename['size'];

				$upload_path = 'uploads/media/source/';



				$content_type = $filename['type'];
				
				// Name of content on S3
				
				$content_title = $project_name.'/'.str_replace("./", '', $upload_path).$new_file_name;

				// Service name for S3
				$aws_service_name = 's3';

				// UTC timestamp and date
				$timestamp = gmdate('Ymd\THis\Z');
				$date = gmdate('Ymd');


				// HTTP request headers as key & value
				$request_headers = array();
				$request_headers['Content-Type'] = $content_type;
				$request_headers['Content-Length'] = $content_length;
				$request_headers['X-Amz-Date'] = $timestamp;
				$request_headers['Host'] = $host_name;
				//$request_headers['x-amz-acl'] = $content_acl;
				$request_headers['X-Amz-Content-Sha256'] = hash('sha256', $content);
				// Sort it in ascending order
				ksort($request_headers);

				// Canonical headers
				$canonical_headers = [];
				foreach($request_headers as $key => $value) {
					$canonical_headers[] = strtolower($key) . ":" . $value;
				}
				$canonical_headers = implode("\n", $canonical_headers);

				// Signed headers
				$signed_headers = [];
				foreach($request_headers as $key => $value) {
					$signed_headers[] = strtolower($key);
				}
				$signed_headers = implode(";", $signed_headers);

				// Cannonical request 
				$canonical_request = [];
				$canonical_request[] = "PUT";
				$canonical_request[] = "/" . $content_title;
				$canonical_request[] = "";
				$canonical_request[] = $canonical_headers;
				$canonical_request[] = "";
				$canonical_request[] = $signed_headers;
				$canonical_request[] = hash('sha256', $content);
				$canonical_request = implode("\n", $canonical_request);
				$hashed_canonical_request = hash('sha256', $canonical_request);

				// AWS Scope
				$scope = [];
				$scope[] = $date;
				$scope[] = $aws_region;
				$scope[] = $aws_service_name;
				$scope[] = "aws4_request";

				// String to sign
				$string_to_sign = [];
				$string_to_sign[] = "AWS4-HMAC-SHA256"; 
				$string_to_sign[] = $timestamp; 
				$string_to_sign[] = implode('/', $scope);
				$string_to_sign[] = $hashed_canonical_request;
				$string_to_sign = implode("\n", $string_to_sign);

				// Signing key
				$kSecret = 'AWS4' . $aws_secret_access_key;
				$kDate = hash_hmac('sha256', $date, $kSecret, true);
				$kRegion = hash_hmac('sha256', $aws_region, $kDate, true);
				$kService = hash_hmac('sha256', $aws_service_name, $kRegion, true);
				$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);

				// Signature
				$signature = hash_hmac('sha256', $string_to_sign, $kSigning);

				// Authorization
				$authorization = [
					'Credential=' . $aws_access_key_id . '/' . implode('/', $scope),
					'SignedHeaders=' . $signed_headers,
					'Signature=' . $signature,
				];
				$authorization = 'AWS4-HMAC-SHA256' . ' ' . implode( ',', $authorization);

				// Curl headers
				$curl_headers = [ 'Authorization: ' . $authorization ];
				foreach($request_headers as $key => $value) {
					$curl_headers[] = $key . ": " . $value;
				}

				//dump($curl_headers);

				$url = 'https://' . $host_name . '/' . $content_title;
				$ch = curl_init($url);
				curl_setopt($ch, CURLOPT_HEADER, false);
				curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
				curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
				curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
				curl_exec($ch);
				$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
				$returnArr = array();
				if($http_code != 200){
					$returnArr["status"] = FALSE;
					$returnArr["message"] = 'Error : Failed to upload';
					return $returnArr;
				}else{
					$returnArr["status"] = TRUE;
					$returnArr["message"] = "Success";
					$returnArr["image_name"] = $new_file_name;
				}

				unlink('./uploads/'.$filename['name']);

		        return $returnArr;
			}else{
				$returnArr["status"] = FALSE;
				$returnArr["message"] = "Invalid credentials";
				return $returnArr;
			}
		}

		public function putZipObject($old_path, $filename, $project_name, $aws_result = array()){
			if(!empty($aws_result)){
				$aws_access_key_id = trim($aws_result['access_key_id']);
				$aws_secret_access_key = trim($aws_result['secret_access_key']);

				// Bucket
				$bucket_name = trim($aws_result['bucket_name']);


				$aws_region = trim($aws_result['region_name']);
				$host_name = $bucket_name . '.s3.'.$aws_region.'.amazonaws.com';

				$new_file_name = $this->random_string_create(6).'-'.str_replace(" ", "-", $this->clean($filename));
				$extension = $this->getExtension($filename);

				$a = $this->clean($filename['name']);
				$path_parts = pathinfo($a);
				$a_without_ext = $path_parts['filename'];
				$extension = $this->getExtension($a);

				if($a_without_ext != "" && $extension != ""){
					$new_file_name = $a_without_ext.'_'.$this->random_string_create(4).'.'.$extension;
				}
				

				$content_type = mime_content_type($old_path.''.$filename);
				$image_type = array('image/jpeg','image/jpg','image/png','image/x-png');


	        	if(in_array($content_type, $image_type)){

	        		$content_path = $old_path.''.$filename;
					$content = file_get_contents($content_path);

					$new_img = get_headers(base_url().str_replace("./", "", str_replace(' ', '%20', $old_path)).''.$filename, 1);
					$content_length = $new_img["Content-Length"];

					$upload_path = 'uploads/media/source/';
			        	
						
					// Name of content on S3
					
					$content_title = $project_name.'/'.str_replace("./", '', $upload_path).$new_file_name;

					// Service name for S3
					$aws_service_name = 's3';

					// UTC timestamp and date
					$timestamp = gmdate('Ymd\THis\Z');
					$date = gmdate('Ymd');


					// HTTP request headers as key & value
					$request_headers = array();
					$request_headers['Content-Type'] = $content_type;
					$request_headers['Content-Length'] = $content_length;
					$request_headers['X-Amz-Date'] = $timestamp;
					$request_headers['Host'] = $host_name;
					//$request_headers['x-amz-acl'] = $content_acl;
					$request_headers['X-Amz-Content-Sha256'] = hash('sha256', $content);
					// Sort it in ascending order
					ksort($request_headers);

					// Canonical headers
					$canonical_headers = [];
					foreach($request_headers as $key => $value) {
						$canonical_headers[] = strtolower($key) . ":" . $value;
					}
					$canonical_headers = implode("\n", $canonical_headers);

					// Signed headers
					$signed_headers = [];
					foreach($request_headers as $key => $value) {
						$signed_headers[] = strtolower($key);
					}
					$signed_headers = implode(";", $signed_headers);

					// Cannonical request 
					$canonical_request = [];
					$canonical_request[] = "PUT";
					$canonical_request[] = "/" . $content_title;
					$canonical_request[] = "";
					$canonical_request[] = $canonical_headers;
					$canonical_request[] = "";
					$canonical_request[] = $signed_headers;
					$canonical_request[] = hash('sha256', $content);
					$canonical_request = implode("\n", $canonical_request);
					$hashed_canonical_request = hash('sha256', $canonical_request);

					// AWS Scope
					$scope = [];
					$scope[] = $date;
					$scope[] = $aws_region;
					$scope[] = $aws_service_name;
					$scope[] = "aws4_request";

					// String to sign
					$string_to_sign = [];
					$string_to_sign[] = "AWS4-HMAC-SHA256"; 
					$string_to_sign[] = $timestamp; 
					$string_to_sign[] = implode('/', $scope);
					$string_to_sign[] = $hashed_canonical_request;
					$string_to_sign = implode("\n", $string_to_sign);

					// Signing key
					$kSecret = 'AWS4' . $aws_secret_access_key;
					$kDate = hash_hmac('sha256', $date, $kSecret, true);
					$kRegion = hash_hmac('sha256', $aws_region, $kDate, true);
					$kService = hash_hmac('sha256', $aws_service_name, $kRegion, true);
					$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);

					// Signature
					$signature = hash_hmac('sha256', $string_to_sign, $kSigning);

					// Authorization
					$authorization = [
						'Credential=' . $aws_access_key_id . '/' . implode('/', $scope),
						'SignedHeaders=' . $signed_headers,
						'Signature=' . $signature,
					];
					$authorization = 'AWS4-HMAC-SHA256' . ' ' . implode( ',', $authorization);

					// Curl headers
					$curl_headers = [ 'Authorization: ' . $authorization ];
					foreach($request_headers as $key => $value) {
						$curl_headers[] = $key . ": " . $value;
					}

					if(ob_get_level()) ob_end_clean();

					$url = 'https://' . $host_name . '/' . $content_title;
					$ch = curl_init($url);
					curl_setopt($ch, CURLOPT_HEADER, false);
					curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
					curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
					curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
					curl_exec($ch);
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
					$returnArr = array();
					if($http_code != 200){
						$returnArr["status"] = FALSE;
						$returnArr["message"] = 'Error : Failed to upload';
						return $returnArr;
					}else{
						$returnArr["status"] = TRUE;
						$returnArr["message"] = "Success";
						$returnArr["image_name"] = $new_file_name;
					}

			    }

			    return $returnArr;


			}else{
				$returnArr["status"] = FALSE;
				$returnArr["message"] = "Invalid credentials";
				return $returnArr;
			}
		}

		public function getExtension($str) {

			$i = strrpos($str,".");
			if (!$i) { return ""; } 
			$l = strlen($str) - $i;
			$ext = substr($str,$i+1,$l);
			return strtolower($ext);
 		}

 		public function clean($string) {
		   $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.

		   return preg_replace("/[^a-z0-9\_\-\.]/i", '', $string); // Removes special chars.
		}

		public function random_string_create($length = 4){
	        $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
	        $str = '';
	        $max = strlen($characters) - 1;
	        for ($i = 0; $i < $length  ; $i++) {
	            $str .= $characters[mt_rand(0, $max)];
	        }
	        return $str; 
	    }

		public function putPDFObject($old_path, $filename, $project_name, $aws_result = array()){
			if(!empty($aws_result)){
				$aws_access_key_id = trim($aws_result['access_key_id']);
				$aws_secret_access_key = trim($aws_result['secret_access_key']);

				// Bucket
				$bucket_name = trim($aws_result['bucket_name']);


				$aws_region = trim($aws_result['region_name']);
				$host_name = $bucket_name . '.s3.'.$aws_region.'.amazonaws.com';

				$new_file_name = $filename;
				$extension = $this->getExtension($filename);
				

        		$content_path = $old_path.''.$filename;
				$content = file_get_contents($content_path);

				$new_img = get_headers(base_url().str_replace("./", "", str_replace(' ', '%20', $old_path)).''.$filename, 1);
				$content_length = $new_img["Content-Length"];

				$upload_path = 'uploads/invoice/';
					
				// Name of content on S3
				
				$content_title = $project_name.'/'.str_replace("./", '', $upload_path).$new_file_name;

				// Service name for S3
				$aws_service_name = 's3';

				// UTC timestamp and date
				$timestamp = gmdate('Ymd\THis\Z');
				$date = gmdate('Ymd');


				// HTTP request headers as key & value
				$request_headers = array();
				$request_headers['Content-Type'] = $content_type;
				$request_headers['Content-Length'] = $content_length;
				$request_headers['X-Amz-Date'] = $timestamp;
				$request_headers['Host'] = $host_name;
				//$request_headers['x-amz-acl'] = $content_acl;
				$request_headers['X-Amz-Content-Sha256'] = hash('sha256', $content);
				// Sort it in ascending order
				ksort($request_headers);

				// Canonical headers
				$canonical_headers = [];
				foreach($request_headers as $key => $value) {
					$canonical_headers[] = strtolower($key) . ":" . $value;
				}
				$canonical_headers = implode("\n", $canonical_headers);

				// Signed headers
				$signed_headers = [];
				foreach($request_headers as $key => $value) {
					$signed_headers[] = strtolower($key);
				}
				$signed_headers = implode(";", $signed_headers);

				// Cannonical request 
				$canonical_request = [];
				$canonical_request[] = "PUT";
				$canonical_request[] = "/" . $content_title;
				$canonical_request[] = "";
				$canonical_request[] = $canonical_headers;
				$canonical_request[] = "";
				$canonical_request[] = $signed_headers;
				$canonical_request[] = hash('sha256', $content);
				$canonical_request = implode("\n", $canonical_request);
				$hashed_canonical_request = hash('sha256', $canonical_request);

				// AWS Scope
				$scope = [];
				$scope[] = $date;
				$scope[] = $aws_region;
				$scope[] = $aws_service_name;
				$scope[] = "aws4_request";

				// String to sign
				$string_to_sign = [];
				$string_to_sign[] = "AWS4-HMAC-SHA256"; 
				$string_to_sign[] = $timestamp; 
				$string_to_sign[] = implode('/', $scope);
				$string_to_sign[] = $hashed_canonical_request;
				$string_to_sign = implode("\n", $string_to_sign);

				// Signing key
				$kSecret = 'AWS4' . $aws_secret_access_key;
				$kDate = hash_hmac('sha256', $date, $kSecret, true);
				$kRegion = hash_hmac('sha256', $aws_region, $kDate, true);
				$kService = hash_hmac('sha256', $aws_service_name, $kRegion, true);
				$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);

				// Signature
				$signature = hash_hmac('sha256', $string_to_sign, $kSigning);

				// Authorization
				$authorization = [
					'Credential=' . $aws_access_key_id . '/' . implode('/', $scope),
					'SignedHeaders=' . $signed_headers,
					'Signature=' . $signature,
				];
				$authorization = 'AWS4-HMAC-SHA256' . ' ' . implode( ',', $authorization);

				// Curl headers
				$curl_headers = [ 'Authorization: ' . $authorization ];
				foreach($request_headers as $key => $value) {
					$curl_headers[] = $key . ": " . $value;
				}

				$url = 'https://' . $host_name . '/' . $content_title;
				$ch = curl_init($url);
				curl_setopt($ch, CURLOPT_HEADER, false);
				curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
				curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
				curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
				curl_exec($ch);
				$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
				$returnArr = array();
				if($http_code != 200){
					$returnArr["status"] = FALSE;
					$returnArr["message"] = 'Error : Failed to upload';
					return $returnArr;
				}else{
					$returnArr["status"] = TRUE;
					$returnArr["message"] = "Success";
					$returnArr["image_name"] = $new_file_name;
				}
		        

			    return $returnArr;


			}else{
				$returnArr["status"] = FALSE;
				$returnArr["message"] = "Invalid credentials";
				return $returnArr;
			}
		}
	}
?>