<?php

namespace App\Packages\Core\Repository;

use Closure;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;

/**
 * Class AbstractRepository
 * @package App\Packages\Core\Repository
 */
class AbstractRepository
{
	/** @var Model */
	protected $model;

	/**
	 * AbstractRepository constructor.
	 *
	 * @param $modelClassName
	 *
	 * @throws Exception
	 */
	public function __construct($modelClassName)
	{
		$this->model = new $modelClassName();

		if (!($this->model instanceof Model)) {
			throw new Exception('$model must be instance of Illuminate\Database\Eloquent\Model class');
		}
	}

	/**
	 * @return Model
	 */
	public function getModel()
	{
		return $this->model;
	}

	/**
	 * @param string|array|Closure $whereColumns
	 *
	 * @return Collection|static[]
	 */
	public function all($whereColumns = [])
	{
		return $this->query()
			->where($whereColumns)
			->get();
	}

	/**
	 * @return Builder
	 */
	public function query()
	{
		return $this->model
			->query();
	}

	/**
	 * @param string|array|Closure $whereColumns
	 *
	 * @return Model|static
	 */
	public function firstOrFail($whereColumns = [])
	{
		return $this->query()
			->where($whereColumns)
			->firstOrFail();
	}

	/**
	 * @param string|array|Closure $whereColumns
	 *
	 * @return null|object|static
	 */
	public function first($whereColumns = [])
	{
		return $this->query()
			->where($whereColumns)
			->first();
	}

	/**
	 * @param int $id
	 *
	 * @return null|object|static
	 */
	public function firstById($id)
	{
		return $this->query()
			->where([['id', '=', $id]])
			->first();
	}
}
