<?php
/**
 * Trait DotArray
 *
 * @filesource   DotArray.php
 * @created      13.11.2017
 * @package      chillerlan\Traits\ArrayHelpers
 * @author       Smiley <smiley@chillerlan.net>
 * @copyright    2017 Smiley
 * @license      MIT
 */

namespace chillerlan\Traits\ArrayHelpers;

/**
 * @link https://github.com/laravel/framework/blob/5.4/src/Illuminate/Support/Arr.php
 */
trait DotArray {

	/**
	 * @var array
	 */
	protected $array = array();

	/**
	 *  Checks if $key isset in $array using dot notation and returns it on success.
	 *
	 * @param string $dotKey  the key to search
	 * @param mixed  $default [optional] a default value in case the key isn't being found
	 *
	 * @return mixed returns $array[$key], $default otherwise.
	 */
	public function get( string $dotKey, $default = null) {

		if (isset($this->array[$dotKey])) {
			return $this->array[$dotKey];
		}

		$array = &$this->array;

		foreach (explode('.', $dotKey) as $segment) {

			if (!is_array($array) || !array_key_exists($segment, $array)) {
				return $default;
			}

			$array = &$array[$segment];
		}

		return $array;
	}

	/**
	 * Checks if $key exists in $array using dot notation and returns it on success
	 *
	 * @param string $dotKey the key to search
	 *
	 * @return bool
	 */
	public function in( string $dotKey):bool {

		if (empty($this->array)) {
			return false;
		}

		if (array_key_exists($dotKey, $this->array)) {
			return true;
		}

		$array = &$this->array;

		foreach (explode('.', $dotKey) as $segment) {

			if (!is_array($array) || !array_key_exists($segment, $array)) {
				return false;
			}

			$array = &$array[$segment];
		}

		return true;
	}

	/**
	 * Sets $key in $array using dot notation
	 *
	 * If no key is given to the method, the entire array will be replaced.
	 *
	 * @param  string $dotKey
	 * @param  mixed  $value
	 *
	 * @return \chillerlan\Traits\ArrayHelpers\DotArray
	 */
	public function set( string $dotKey, $value) {

		if (empty($dotKey)) {
			$this->array = $value;

			return $this;
		}

		$array = &$this->array;
		$keys = explode('.', $dotKey);

		while (count($keys) > 1) {
			$dotKey = array_shift($keys);

			// If the key doesn't exist at this depth, we will just create an empty array
			// to hold the next value, allowing us to create the arrays to hold final
			// values at the correct depth. Then we'll keep digging into the array.
			if (!isset($array[$dotKey]) || !is_array($array[$dotKey])) {
				$array[$dotKey] = array();
			}

			$array = &$array[$dotKey];
		}

		$array[array_shift($keys)] = $value;

		return $this;
	}

}
