<?php

namespace Account;


use Analyst\Core\AbstractFactory;

/**
 * Class AccountDataFactory
 *
 * Holds information about this
 * wordpress project plugins accounts
 *
 */
class AccountDataFactory extends AbstractFactory
{
	private static $instance;

	CONST OPTIONS_KEY = 'analyst_accounts_data';

	/**
	 * @var AccountData[]
	 */
	protected $accounts = [];

	/**
	 * Read factory from options or make fresh instance
	 *
	 * @return static
	 */
	public static function instance()
	{
		if (!static::$instance) {
			$raw = get_option(self::OPTIONS_KEY);

			// In case object is already unserialized
			// and instance of AccountDataFactory we
			// return it, in other case deal with
			// serialized string data
			if ($raw instanceof self) {
				static::$instance = $raw;
			} else {
				static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
			}
		}

		return static::$instance;
	}

	/**
	 * Sync this object data with cache
	 */
	public function sync()
	{
		update_option(self::OPTIONS_KEY, serialize($this));
	}

	/**
	 * Sync this instance data with cache
	 */
	public static function syncData()
	{
		static::instance()->sync();
	}

	/**
	 * Find plugin account data or create fresh one
	 *
	 * @param Account $account
	 * @return AccountData|null
	 */
	public function resolvePluginAccountData(Account $account)
	{
		$accountData = $this->findAccountDataById($account->getId());

		if (!$accountData) {
			$accountData = new AccountData();

			// Set proper default values
			$accountData->setPath($account->getPath());
			$accountData->setId($account->getId());
			$accountData->setSecret($account->getClientSecret());

			array_push($this->accounts, $accountData);
		}

		return $accountData;
	}

	/**
	 * Should return account data by base path
	 *
	 * @param $basePath
	 * @return AccountData
	 */
	public function getAccountDataByBasePath($basePath)
	{
		foreach ($this->accounts as $iterable) {
			$iterableBasePath = plugin_basename($iterable->getPath());

			if ($iterableBasePath === $basePath) {
				return $iterable;
			}
		}

		return null;
	}

	/**
	 * Return account by id
	 *
	 * @param $id
	 * @return AccountData|null
	 */
	private function findAccountDataById($id)
	{
		foreach ($this->accounts as &$iterable) {
			if ($iterable->getId() === $id) {
				return $iterable;
			}
		}

		return null;
	}
}
