<?php

namespace AuthStack\Driver\LDAP;

use Buckhill\LDAP\Client;
use AuthStack\Driver\Errors\NonexistentKeyError;

class Filter
{
    protected $id;
    protected $base;
    protected $filter;
    protected $attributes;

    /**
     * Filter constructor.
     * @param $base
     * @param $filter
     * @param array $attributes
     */
    protected function __construct($id, $base, $filter, array $attributes = [], array $template_vars = [])
    {
        $this->id = $id;
        $this->base = $base;
        $this->filter = $filter;
        $this->attributes = $attributes;
    }

    /**
     * @param array $data
     * @param array $template_vars
     * @return Filter
     * @throws NonexistentKeyError
     */
    public static function fromArray(array $data, array $template_vars = [])
    {
        if (!isset($data['id'])) {
            throw new NonexistentKeyError("Required filter key 'id' not specified.");
        }

        if (!isset($data['baseDN'])) {
            throw new NonexistentKeyError("Required filter key 'baseDN' not specified.");
        }

        if (!isset($data['filter'])) {
            throw new NonexistentKeyError("Required filter key 'filter' not specified.");
        }


        return new static(
            $data['id'],
            $data['baseDN'],
            $data['filter'],
            isset($data['attributes']) ? $data['attributes'] : [],
            $template_vars
        );
    }

    /**
     * @return string
     */
    public function getID()
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getBase()
    {
        return $this->base;
    }

    /**
     * @param null $username
     * @param array $template_vars
     * @return string
     */
    public function getFilterString($username = null, array $template_vars = [])
    {
        $filter = $this->filter;

        if (!empty($username)) {
            $filter = str_replace('{{ uid }}', $username, $filter);
        }

        if (!empty($template_vars)) {
            foreach ($template_vars as $search => $replace) {
                $find = sprintf("{{ %s }}", $search);

                $filter = str_replace($find, $replace, $filter);
            }
        }

        return $filter;
    }

    /**
     * @return array
     */
    public function getAttributes()
    {
        return $this->attributes;
    }

    /**
     * @param Client $connection
     * @param $username
     * @param array $template_vars
     * @return array|\Buckhill\LDAP\EntryCollection
     */
    public function run(Client $connection, $username, array $template_vars = [])
    {
        $filter = $this->getFilterString($username, $template_vars);

        $result = $connection->search($this->getBase(), $filter, $this->getAttributes());

        return $result;
    }
}