<?php namespace Intellex\Curly\Content\TypeHandlers;

use Intellex\Curly\Content\Exception\ContentCannotBeParsedException;
use Intellex\Curly\Content\TypeHandlerInterface;

/**
 * Parses the multipart form data.
 */
class MultipartFormData implements TypeHandlerInterface {

	/** @string    The boundary to use when separating the data. * */
	private $boundary = '@string	The boundary to use when separating the data.';

	/**
	 * Initialize the handlers.
	 *
	 * @param string $type The full content type.
	 */
	public function __construct($type) {
		$this->boundary = preg_replace('~^.+boundary=~', '', $type);
	}

	/**
	 * Extract the values;
	 *
	 * @param string $raw The raw content.
	 *
	 * @return string The extracted data.
	 * @throws ContentCannotBeParsedException
	 */
	public function parse($raw) {
		try {
			$data = [];

			// Split content by boundary and get rid of last -- element
			$blocks = preg_split("~-*{$this->boundary}~", $raw);
			array_pop($blocks);

			// Iterate over found blocks
			foreach ($blocks as $id => $block) {
				if (empty($block)) {
					continue;
				}

				// Uploaded files
				if (strpos($block, 'application/octet-stream') !== false) {
					preg_match('~name="(?<name>[^"]*)".*stream[\n\r]+(?<value>[^\n\r].*)[\n\r]?$~ s', $block, $matches);

					// Other
				} else {
					preg_match('~name="(?<name>[^"]*)"[\n\r]+(?<value>[^\n\r].*)[\n\r]?$~ s', $block, $matches);
				}

				// Error
				if (empty($matches)) {
					throw new ContentCannotBeParsedException('MultipartFormData', $raw);
				}

				$data[] = urlencode($matches['name']) . '=' . urlencode(rtrim($matches['value'], "\r\n"));
			}

			// Parse
			parse_str(implode('&', $data), $parsed);
			return $parsed;

		} catch (\Exception $e) {
			throw new ContentCannotBeParsedException('MultipartFormData', $raw);
		}
	}

	/**
	 * Format the data based on the type.
	 *
	 * @param mixed $data The data to format.
	 *
	 * @return string The formatted data.
	 */
	function format($data) {

		// Handle empty data;
		if (empty($data)) {
			return '';
		}

		// TODO
		return null;
	}

}
