<?php
namespace SabaiApps\Directories\Component\System\Tool;

use SabaiApps\Directories\Context;
use SabaiApps\Directories\Exception;

/**
 * AbstractExportJsonTool provides a base class for tools that export data in JSON format.
 */
abstract class AbstractExportJsonTool extends AbstractTool {

	public function systemToolSettingsForm( $step, array $values, array $parents = array(), ?Context $context = null ) {
		return array(
			'filename' => array(
				'#title'         => __( 'File name', 'directories-pro' ),
				'#type'          => 'textfield',
				'#default_value' => $this->_getDefaultJsonFileName( $context ),
				'#field_suffix'  => '.json',
				'#regex'         => '/^[a-zA-Z0-9-_]+$/',
				'#required'      => true,
				'#horizontal'    => true,
			),
		);
	}

	public function systemToolRunTask( $task, array $settings, $iteration, $total, array &$storage, array &$logs, ?Context $context = null ) {
		try {
			$this->_application->System_Util_validateDirectory( $this->_application->getComponent( 'System' )->getTmpDir(), true );
		} catch ( \Exception $e ) {
			throw new Exception\RuntimeException( $e->getMessage() );
		}

		$files = array();
		$file  = rtrim( $this->_application->getComponent( 'System' )->getTmpDir(), '/' ) . '/' . $settings['filename'] . '.json';
		if ( ! $file
			|| false === ( $fp = fopen( $file, 'w+' ) )
		) {
			throw new Exception\RuntimeException( sprintf( 'Failed opening file %s with write permission', $file ) );
		}

		// Write to JSON file
		$json_encode_option = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT;
		fwrite(
			$fp,
			$this->_application->System_Util_jsonEncode(
				$this->_export( $settings, $context ),
				! empty( $settings['pretty_print'] ) ? $json_encode_option | JSON_PRETTY_PRINT : $json_encode_option
			)
		);
		fclose( $fp );
		$files[]          = $file;
		$storage['files'] = $files;

		return 1;
	}

	public function systemToolComplete( array &$storage, array &$logs, &$downloadFile, ?Context $context = null ) {
		if ( empty( $storage['files'] ) ) {
			return;
		}

		$downloadFile = basename( $storage['files'][0] );
		if ( count( $storage['files'] ) > 1
			&& class_exists( '\ZipArchive', false )
		) {
			$zip      = new \ZipArchive();
			$zip_file = basename( $storage['files'][0], '.csv' ) . '.zip';
			if ( true !== $result = $zip->open( rtrim( dirname( $storage['files'][0] ), '/' ) . '/' . $zip_file, \ZipArchive::CREATE ) ) {
				$logs['error'][] = 'Failed creating zip archive (Error: ' . $this->_application->H( $result ) . ')';
			} else {
				foreach ( $storage['files'] as $file ) {
					$zip->addFile( $file, basename( $file ) );
				}
				$zip->close();
				$downloadFile = $zip_file; // let user download zip file
			}
		}
	}

	abstract protected function _getDefaultJsonFileName( ?Context $context = null );
	abstract protected function _export( array $settings, ?Context $context = null );
}
