<?php

# Put your API Key here !!
You must change here and remove this line
$GLOBALS['APIK'] = "!!! YOUR API KEY HERE !!";

# !!! Local folder to keep sync !!!
You must change here and remove this line (end it with you directory separator / or \)
$GLOBALS['LocalDir'] = "YOUR LOCAL FOLDER HERE";

# Remote folder ID to keep sync (Get it using the API)
You must change here and remove this line
$GLOBALS['RemoteDirId'] = "YOUR REMOTE DIR ID";

#################################################################

# Get files within the local folder
$Files = Array();

if ($handle = opendir($GLOBALS['LocalDir'])) {

    while (false !== ($entry = readdir($handle))) {
				if($entry[0] == '.') continue;
				if(!is_file($GLOBALS['LocalDir'].$entry)) continue;
	
				$sz = filesize($GLOBALS['LocalDir'].$entry);
				if($sz == 0) continue;

				array_push($Files, Array($entry, $sz));
        echo "$entry - $sz\n";
    }
    closedir($handle);
}
else {
	echo "Can't open dir ".$GLOBALS['LocalDir']."\r\n";
	exit;
}

# If no local files to sync, exit
if(count($Files) == 0) {
	echo "No files on our folder!\n";
  exit;
}

# Fetch the remote folder files list
$ch = curl_init('https://api.1fichier.com/v1/file/ls.cgi');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , 'Authorization: Bearer '.$GLOBALS['APIK']));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"pretty":1,"folder_id":'.$GLOBALS['RemoteDirId'].'}'); 
if( !($result = curl_exec($ch))) {
		echo "Request failed : ". curl_error($ch)."\n";
		exit;
} 
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpcode != 200) {
		echo "Request failed : ". $httpcode .'/'.$result.'/'.curl_error($ch)."\n";
		exit;
}
curl_close($ch); 


$Remote = json_decode($result,true);
if(!$Remote) {
		echo "Bad return : ".$result."\n";
		exit;
}

# Compare
echo "Files Local : ".count($Files)." Remote ".$Remote{'count'}."\n";

# Make an objet for the files to sync and another for updated files to rename and sync
$ToUpload = Array();
$ToRenameAndUpload = Array();

# Object to store the new uploaded filenames/urls...
$GLOBALS['Uploaded'] = Array();

# For each files in the local folder
foreach($Files as $v) {
	
    echo "Check for ".$v[0]."\n";

    $found = 0;

    foreach($Remote{'items'} as $v2) {

        # Debug
        # echo "Check vs ".$v2{'filename'}."\n";

        if($v[0] === $v2{'filename'}) {
            
            # Debug : We found the same filename !
            # echo "Filenames Same ".$v[0]." ".$v2{'filename'}."\n";

            # Chek sizes
            if($v[1] != $v2{'size'}) {
                # Sizes differs, must rename and resync (name,size,url)
                array_push($ToRenameAndUpload, Array( $v[0], $v[1], $v2{'url'}));
            }
            $found = 1;
        }
    }

    if(!$found) {
       # If not found on the Remote folder, sync it.
       array_push($ToUpload,  Array($v[0], $v[1]));
    }
}


# Function to upload a file
function fUpload($Item) {
    # If $Item is null, quit.
    if(!$Item) {
        return;
    }
   
		echo "\n*****************************\nUploading: ".$Item[0]."\n";
 
    # Get Upload Node and ID
		$ch = curl_init('https://api.1fichier.com/v1/upload/get_upload_server.cgi');
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_POST, 1); 
		if( !($result = curl_exec($ch))) {
			echo "Request failed : ". curl_error($ch)."\n";
			exit;
		} 
		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($httpcode != 200) {
			echo "Request failed : ". $httpcode .'/'.$result.'/'.curl_error($ch)."\n";
			exit;
		}
		curl_close($ch); 

		$NID = json_decode($result,true);
		if(!$NID) {
			echo "Bad return : ".$result."\n";
			exit;
		}

    echo "Using node: ".$NID{'url'}."\n";

		$ch = curl_init('https://'.$NID{'url'}.'/upload.cgi?id='.$NID{'id'});
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$GLOBALS['APIK'], 'Content-Type: multipart/form-data'));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_HEADER, true); 
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 
		curl_setopt($ch, CURLOPT_POSTFIELDS, array('did' => $GLOBALS['RemoteDirId'], 'file[]' => new CURLFile($GLOBALS['LocalDir'].$Item[0])) ); 
		if( !($result = curl_exec($ch))) {
			echo "Request failed : ". curl_error($ch)."\n";
			exit;
		}
		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($httpcode != 302) {
			echo "Request failed : ". $httpcode .'/'.$result.'/'.curl_error($ch)."\n";
			exit;
		}
		curl_close($ch);

		$ch = curl_init('https://'.$NID{'url'}.'/end.pl?xid='.$NID{'id'});
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('JSON: 1'));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 
		if( !($result = curl_exec($ch))) {
			echo "Request failed : ". curl_error($ch)."\n";
			exit;
		}
		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($httpcode != 200) {
			echo "Request failed : ". $httpcode .'/'.$result.'/'.curl_error($ch)."\n";
			exit;
		}
		curl_close($ch);

		$js = json_decode($result);

		if(!$js) {
			echo "Request failed: ".$result."\n";
			exit;
		}

		if(!$js->links[0]) {
			echo "Bad ret: ".$result."\n";
			exit;
		}

		# File upload success
		echo "File " .$js->links[0]->filename." Uploaded OK / Download link : ".$js->links[0]->download."\n";

		# Store it to make a resume at the end
	  array_push($GLOBALS['Uploaded'], Array($js->links[0]->filename, $js->links[0]->download));
}

function fRename($Item) {
    if(!$Item) {
        return;
    }

    # Rename the existing file that have a different size to filename_timestamp
    echo "\n************************************\nRename URL ".$Item[2]."\n";

		$ch = curl_init('https://api.1fichier.com/v1/file/rename.cgi');
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , 'Authorization: Bearer '.$GLOBALS['APIK']));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, '{"pretty":1,"urls":[{"url":"'.$Item[2].'","filename":"'.$Item[0].'_'.time().'"}]}');
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 
		if( !($result = curl_exec($ch))) {
			echo "Request failed : ". curl_error($ch)."\n";
			exit;
		}
		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		if($httpcode != 200) {
			echo "Request failed : ". $httpcode .'/'.$result.'/'.curl_error($ch)."\n";
			exit;
		}
		curl_close($ch);

		#$js = json_decode($result);
		#if(!$js) {
		#	echo "Request failed: ".$result."\n";
		#	exit;
		#}

    return 1;
}

# Files that we only have to sync
echo "\nTo Upload\n";
echo json_encode($ToUpload, JSON_PRETTY_PRINT)."\n";

foreach($ToUpload as $v) {
	fUpload($v);
}

# Files that we have to rename fist and sync after
echo "\nTo Rename and Upload\n";
echo json_encode($ToRenameAndUpload, JSON_PRETTY_PRINT)."\n";
foreach($ToRenameAndUpload as $v) {

    if(fRename($v)) {
        fUpload($v);
    }
    else {
        echo "Rename failed!\n";
        exit;
    }
}

# Print the final resume
echo "\nNew uploaded files\n";
echo json_encode($GLOBALS['Uploaded'], JSON_PRETTY_PRINT)."\n";

?>
