<?php
/**
 *
 */
class BackWPup_Destination_Folder extends BackWPup_Destinations {


	/**
	 * @return array
	 */
	public function option_defaults() {

		$upload_dir = wp_upload_dir( null, false, true );
		$backups_dir = trailingslashit( str_replace( '\\', '/',$upload_dir[ 'basedir' ] ) ) . 'backwpup-' . BackWPup::get_plugin_data( 'hash' ) . '-backups/';
		$content_path = trailingslashit( str_replace( '\\', '/', WP_CONTENT_DIR ) );
		$backups_dir = str_replace( $content_path, '', $backups_dir );

		return array( 'maxbackups' => 15, 'backupdir' => $backups_dir, 'backupsyncnodelete' => TRUE );
	}


	/**
	 * @param $jobid
	 * @return void
	 * @internal param $main
	 */
	public function edit_tab( $jobid ) {
		?>
    <h3 class="title"><?php esc_html_e( 'Backup settings', 'backwpup' ); ?></h3>
    <p></p>
    <table class="form-table">
        <tr>
            <th scope="row"><label for="idbackupdir"><?php esc_html_e( 'Folder to store backups in', 'backwpup' ); ?></label></th>
            <td>
                <input name="backupdir" id="idbackupdir" type="text" value="<?php echo esc_attr( BackWPup_Option::get( $jobid, 'backupdir' ) ); ?>" class="regular-text" />
            </td>
        </tr>
        <tr>
            <th scope="row"><?php esc_html_e( 'File Deletion', 'backwpup' ); ?></th>
            <td>
	            <?php
	            if ( BackWPup_Option::get( $jobid, 'backuptype' ) === 'archive' ) {
		            ?>
		            <label for="idmaxbackups">
			            <input id="idmaxbackups" name="maxbackups" type="number" min="0" step="1" value="<?php echo esc_attr( BackWPup_Option::get( $jobid, 'maxbackups' ) ); ?>" class="small-text"/>
			            &nbsp;<?php esc_html_e( 'Number of files to keep in folder.', 'backwpup' ); ?>
		            </label>
		            <p><?php _e( '<strong>Warning</strong>: Files belonging to this job are now tracked. Old backup archives which are untracked will not be automatically deleted.', 'backwpup' ) ?></p>
	            <?php } else { ?>
		            <label for="idbackupsyncnodelete">
			            <input class="checkbox" value="1" type="checkbox" <?php checked( BackWPup_Option::get( $jobid, 'backupsyncnodelete' ), true ); ?> name="backupsyncnodelete" id="idbackupsyncnodelete"/>
			            &nbsp;<?php esc_html_e( 'Do not delete files while syncing to destination!', 'backwpup' ); ?>
		            </label>
	            <?php } ?>
            </td>
        </tr>
    </table>
	<?php
	}


	/**
	 * @param $jobid
	 */
	public function edit_form_post_save( $jobid ) {

		$_POST[ 'backupdir' ] = trailingslashit( str_replace( array( '//', '\\' ), '/', trim( sanitize_text_field( $_POST[ 'backupdir' ] ) ) ) );
		BackWPup_Option::update( $jobid, 'backupdir', $_POST[ 'backupdir' ] );

		BackWPup_Option::update( $jobid, 'maxbackups', ! empty( $_POST[ 'maxbackups' ] ) ? absint( $_POST[ 'maxbackups' ] ) : 0 );
		BackWPup_Option::update( $jobid, 'backupsyncnodelete', ! empty( $_POST[ 'backupsyncnodelete' ] ) );
	}

	/**
	 * @param $jobdest
	 * @param $backupfile
	 */
	public function file_delete( $jobdest, $backupfile ) {

		list( $jobid, $dest ) = explode( '_', $jobdest, 2 );

		if ( empty( $jobid ) ) {
			return;
		}

		$backup_dir = esc_attr( BackWPup_Option::get( (int)$jobid, 'backupdir' ) );
		$backup_dir = BackWPup_File::get_absolute_path( $backup_dir );

		$backupfile =  realpath( trailingslashit( $backup_dir ) . basename( $backupfile ) );

		if ( $backupfile && is_writeable( $backupfile ) && !is_dir( $backupfile ) && !is_link( $backupfile ) ) {
			 unlink( $backupfile );
		}
	}

	/**
	 * @param $jobid
	 * @param $get_file
	 */
	public function file_download( $jobid, $get_file ) {

		$backup_dir = esc_attr( BackWPup_Option::get( (int) $jobid, 'backupdir' ) );
		$backup_dir = BackWPup_File::get_absolute_path( $backup_dir );

		$get_file = realpath( trailingslashit( $backup_dir ) . basename( $get_file ) );

		if ( $get_file && is_readable( $get_file ) ) {
			if ( $level = ob_get_level() ) {
				for ( $i = 0; $i < $level; $i ++ ) {
					ob_end_clean();
				}
			}
			@set_time_limit( 300 );
			nocache_headers();
			header( 'Content-Description: File Transfer' );
			header( 'Content-Type: ' . BackWPup_Job::get_mime_type( $get_file ) );
			header( 'Content-Disposition: attachment; filename="' . basename( $get_file ) . '"' );
			header( 'Content-Transfer-Encoding: binary' );
			header( 'Content-Length: ' . filesize( $get_file ) );
			$handle = fopen( $get_file, 'rb' );
			if ( $handle ) {
				while ( ! feof( $handle ) ) {
					echo fread( $handle, 10241024 ); //chunks
					flush();
				}
				fclose( $handle );
			}
			die();
		} else {
			header( $_SERVER["SERVER_PROTOCOL"] . " 404 Not Found" );
			header( "Status: 404 Not Found" );
			die();
		}
	}

	/**
	 * @param $jobdest
	 * @return mixed
	 */
	public function file_get_list( $jobdest ) {

		list( $jobid, $dest ) = explode( '_', $jobdest, 2 );
		$filecounter    = 0;
		$files          = array();
		$backup_folder  = BackWPup_Option::get( $jobid, 'backupdir' );
		$backup_folder  = BackWPup_File::get_absolute_path( $backup_folder );

		if ( is_dir( $backup_folder ) ) { //make file list
			$dir = new BackWPup_Directory( $backup_folder );

			foreach ( $dir as $file ) {
				if ( $file->isDot() || in_array( $file->getFilename(), array( 'index.php', '.htaccess', '.donotbackup', 'Web.config' ), true ) || $file->isDir() || $file->isLink() ) {
					continue;
				}

				if ( $file->isReadable() ) {
					//file list for backups
					$files[ $filecounter ][ 'folder' ]      = $backup_folder;
					$files[ $filecounter ][ 'file' ]        = str_replace( '\\', '/', $file->getPathname() );
					$files[ $filecounter ][ 'filename' ]    = $file->getFilename();
					$files[ $filecounter ][ 'downloadurl' ] = add_query_arg( array(
																				  'page'   => 'backwpupbackups',
																				  'action' => 'downloadfolder',
																				  'file'   => $file->getFilename(),
																				  'jobid'  => $jobid
																			 ), network_admin_url( 'admin.php' ) );
					$files[ $filecounter ][ 'filesize' ]    = $file->getSize();
					$files[ $filecounter ][ 'time' ]        = $file->getMTime() + ( get_option( 'gmt_offset' ) * 3600 );
					$filecounter ++;
				}
			}
		}

		return $files;
	}

	/**
	 * @param $job_object
	 * @return bool
	 */
	public function job_run_archive( BackWPup_Job $job_object ) {

		$job_object->substeps_todo = 1;
		if ( ! empty( $job_object->job[ 'jobid' ] ) )
			BackWPup_Option::update( $job_object->job[ 'jobid' ], 'lastbackupdownloadurl', add_query_arg( array(
																								  'page'   => 'backwpupbackups',
																								  'action' => 'downloadfolder',
																								  'file'   => basename( $job_object->backup_file ),
																								  'jobid'  => $job_object->job[ 'jobid' ]
																							 ), network_admin_url( 'admin.php' ) ) );
		//Delete old Backupfiles
		$backupfilelist = array();
		$files          = array();

		if ( is_writable( $job_object->backup_folder ) ) { //make file list
			try {
				$dir = new BackWPup_Directory( $job_object->backup_folder );

				foreach ( $dir as $file ) {
					if ( $file->isWritable() && ! $file->isDir() && ! $file->isLink() ) {
						//list for deletion
						if ( $job_object->is_backup_archive( $file->getFilename() ) && $job_object->owns_backup_archive( $file->getFilename() ) ) {
							$backupfilelist[ $file->getMTime() ] = clone $file;
						}
					}
				}
			}
			catch ( UnexpectedValueException $e ) {
				$job_object->log( sprintf( __( "Could not open path: %s", 'backwpup' ), $e->getMessage() ), E_USER_WARNING );
			}
		}

		if ( $job_object->job[ 'maxbackups' ] > 0 ) {
			if ( count( $backupfilelist ) > $job_object->job[ 'maxbackups' ] ) {
				ksort( $backupfilelist );
				$numdeltefiles = 0;
				while ( $file = array_shift( $backupfilelist ) ) {
					if ( count( $backupfilelist ) < $job_object->job[ 'maxbackups' ] )
						break;
					unlink( $file->getPathname() );
					foreach ( $files as $key => $filedata ) {
						if ( $filedata[ 'file' ] == $file->getPathname() ) {
							unset( $files[ $key ] );
						}
					}
					$numdeltefiles ++;
				}
				if ( $numdeltefiles > 0 )
					$job_object->log( sprintf( _n( 'One backup file deleted', '%d backup files deleted', $numdeltefiles, 'backwpup' ), $numdeltefiles ), E_USER_NOTICE );
			}
		}

		$job_object->substeps_done ++;

		return TRUE;
	}

	/**
	 * @param $job_settings array
	 * @return bool
	 */
	public function can_run( array $job_settings ) {

		if ( empty( $job_settings[ 'backupdir' ] ) || $job_settings[ 'backupdir' ] == '/' )
			return FALSE;

		return TRUE;
	}

}
